Friday, May 09, 2008

この記事は

記事 関数名 説明
SQL*PLUSもどきを作る1 PSOracle SQL*PLUSもどきのメイン関数
SQL*PLUSもどきを作る1の説明 PSOracle SQL*PLUSもどきのメイン関数の説明
SQL*PLUSもどきを作る2 Get-OracleConnectionStirng 接続文字列を作成する
SQL*PLUSもどきを作る3 Execute-QueryString SQLを実行した結果をDataSetに格納して返す
SQL*PLUSもどきを作る4 desc descコマンド
SQL*PLUSもどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る
SQL*PLUSもどきを作る6 Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する
SQL*PLUSもどきを作る7 Disconnect 切断処理

の続きです。

今回は、実行したSQLの履歴を保存する Write-SqlHistoryという関数を作成したので紹介します。

#================================================================================================
# Write-SqlHistory: SQL実行履歴の作成
#
# UPDATE: 2008-05-09 Ver.1.0.0
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#================================================================================================
function global:Write-SqlHistory([string]$SQL)
{
  #保存可能な履歴数
  $MaxHistory = 100
  $SaveFile = "$([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle\History.xml"
  
  $UPDT = (Get-Date).ToString("yyyy/MM/dd hh:mm:ss")
  if ( Test-Path $SaveFile )
  {
    #データセットの作成
    $dtSet = New-Object System.Data.DataSet("History_Data")
    #既存ファイルの読み込み
    [void]$dtSet.ReadXml($SaveFile)
    
    #データテーブルの取り出し
    $dtTbl = $dtSet.tables[0]
    
    #保存可能数を超えた場合
    if ( $dtTbl.Rows.Count -ge $MaxHistory )
    {
      #最初の行を削除
      $dtTbl.Rows[0].Delete()
    }
    
    #新規レコードの作成
    $dtRow = $dtTbl.NewRow()
    #データをセット
    $dtRow["UPDT"] = $UPDT
    $dtRow["SQL"] = $SQL
    #データテーブルにレコードの追加
    $dtTbl.Rows.Add($dtRow)
    #XMLファイルを作成
    $dtSet.WriteXml($SaveFile)
  }
  else
  {
    #Xmlセッティングの作成
    $settings = New-Object System.Xml.XmlWriterSettings
    #エンコーディングの指定
    $settings.Encoding = [System.Text.Encoding]::UTF8
    #インデントの指定
    $settings.Indent = $True

    #XmlWriterの作成
    $xmlWriter = [System.Xml.XmlWriter]::Create($savefile, $settings)
    #要素の追加
    $xmlWriter.WriteStartElement("History_Data")
    $xmlWriter.WriteStartElement("History")
    $xmlWriter.WriteElementString("UPDT",$UPDT)
    $xmlWriter.WriteElementString("SQL",$SQL)
    [void]$xmlWriter.WriteEndElement
    #XmlWriterのClose
    $xmlWriter.Close()
  }
}

この関数は

PS > Write-SqlHistory "SELECT * FROM EMP"

のように使用します。

関数が実行されると

<?xml version="1.0" standalone="yes"?>
<History_Data>
  <History>
    <UPDT>2008/05/09 11:03:38</UPDT>
    <SQL>select * from emp</SQL>
  </History>
  <History>
    <UPDT>2008/05/09 11:03:45</UPDT>
    <SQL>select * from tbl2</SQL>
  </History>
</History_Data>

の様なXMLファイルが作成されます。UPDTタグにはSQL実行日時が、SQLタグには実行したSQLが書き込まれます。

開発ポイント

1.保存先の確認
 Test-Pathコマンドレットで保存先のXMLファイルの存在を確認します。
 保存先がある場合はDataSetを使用してXML操作を行います。
 保存先が存在しない場合はXmlWriterで新規にXMLファイルを作成します。

2.新規XMLファイルを作成する
 保存先のXMLファイルが存在しない場合はXmlWriterでXMLファイルを作成するのですが、インデントとエンコーディング指定するために XmlWriterSettings を作成します。 こうしないとインデントがされず読みにくいXMLファイルができてしまいます。
 要素の追加には WriteStartElement を使用し、値の追加は WriteElementString にて行っています。
 要素の追加が終わったら WriteEndElement を実行します。 このとき[void]を付けないと、この行を実行したときにコンソールに実行時の文字列が表示されてしまうので注意が必要です。
 最後にCloseメソッドを実行してXmlWriterを閉じます。

3.既存のXMLファイルを読み込みデータを追加する
 既にXMLファイルが存在する場合にはDataSetを使用してXML操作を行うこととしました。
 まずはNew-Object コマンドレットでDataSetを作成し、ReadXmlメソッドでDataSetに既存XMLを読み込みます。
 DataSetは複数テーブルを格納できるオブジェクトなのでデータが入っている1つめのテーブルだけを変数 $dtTblに取り出します。
 次に、延々と履歴が保存されることのないように上限値に達していないかをチェックします。上限は$MaxHistory変数に100として格納しています。もしもデータ数が上限を超えたら(dtTbl.Rows.Countが100以上)最初の1件のデータを削除するようにしています。(Deleteメソッド)
 あとは$dtTbl.NewRow()で新規レコードを作成し、各要素にデータをセットし、テーブルへの追加を行います。
 最後にDataSetのWriteXmlメソッドを呼び出してXMLファイルを作成します。

Friday, May 09, 2008 2:49:53 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Monday, March 31, 2008

この記事は2008/01/23にわんくまブログで書いたものです。

データを取得してXMLファイルへ保存する(Oracle) (Windows PowerShell Tips)

データを取得してXMLファイルへ保存する その2(Oracle) (Windows PowerShell Tips)

で、Oracleから取得したデータをXML出力する例を紹介しました。

XMLを出力しただけでは見るのが不便なので、簡易XMLビューアを作ってみました。
実行例は下記のとおりです。

 

View-Xml.ps1

#===============================================================================
# View-Xml: XMLファイルを読み込んで表示する(簡易XMLViewer)
#
# 使用例
#   PS > View-Xml XMLファイルパス
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#===============================================================================
function global:View-Xml
{
  Param($XmlFile)

  #パスが指定されているか?
  if ( $XmlFile.Length -eq $null )
  {
    Write-Host "XMLファイルを指定してください"
    return
  }
  
  #存在するパスか?
  if ( -not $(Test-Path $XmlFile) )
  {
    Write-Host $XmlFile + "は存在しません"
    return
  }
  
  #データセットを作成し、XMLファイルを読み込む
  $dtSet = New-Object System.Data.DataSet
  $dtSet.ReadXml($XmlFile)
  
  #===== Formの作成 =====
  [reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
  $form = New-Object System.Windows.Forms.Form
  $form.Text = $XmlFile
  $form.Width = 500
  $form.Height = 400
  
  #===== DataGridViewの作成 =====
  $dgvXML = New-Object System.Windows.Forms.DataGridView
  $dgvXML.Dock = [System.Windows.Forms.DockStyle]::Fill
  $dgvXML.DataSource = $dtSet.Tables[0]
  $form.Controls.Add($dgvXML)
  
  #===== Panelの作成 =====
  $panel1 = New-Object System.Windows.Forms.Panel
  $form.Controls.Add($panel1)
  $panel1.Dock = [System.Windows.Forms.DockStyle]::Bottom
  $panel1.Height = 30
  
  #===== [閉じる]ボタンの作成 =====
  $btnClose = New-Object System.Windows.Forms.Button
  $btnClose.Location = New-Object System.Drawing.Point(405, 4)
  $btnClose.Text = "閉じる"
  $btnClose.anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right
  $btnClose.Add_Click({$form.Close()})
  $panel1.Controls.AddRange($btnClose)
  
  #===== Formを表示 =====
  $form.ShowDialog()
}

使用方法は
View-Xml "XMLファイルのパス"
です。

ポイントは
・データセットを作成して、XMLファイルを読み込む
  $dtSet = New-Object System.Data.DataSet
  $dtSet.ReadXml($XmlFile)


・データセットをDataGridViewに連結する
  $dgvXML.DataSource = $dtSet.Tables[0]

・anchorプロパティ
 anchorプロパティは -bor 演算子を使うとうまくいきます。(-or演算子は試してみたところダメでした)
  -bor はビットごとのOR演算を行います。


です。

あとは、前回までのポイントを御参考下さい。

Monday, March 31, 2008 3:02:28 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

Theme design by Jelle Druyts

Pick a theme: