Saturday, June 07, 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もどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る。終端判定を1文字以上でも行えるよう見直し。
SQL*PLUSもどきを作る7 Disconnect 切断処理

SQL*PLUSもどきを作る8

Write-SqlHistory SQL実行履歴の保存
SQL*PLUSもどきを作る6(改訂版) Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する。SQL実行履歴作成機能の追加。

SQL*PLUSもどきを作る9

View-History SQL履歴からの実行機能作成

SQL*PLUSもどきを作る6(改訂版2)

Execute-Query その9で作成した機能を組み込み、さらにXMLエクスポート機能を付加。

SQL*PLUSもどきを作る10

View-Table SQL実行結果をデータグリッドビューへ表示する機能の作成

の続きです。

前回は、SQL実行結果をデータグリッドビューに表示する部分を作成しました。

今回は、この関数を実際に使用できるようにExecute-Query関数を改造します。

#=========================================================================================
# Execute-Query: QueryStringを実行する
#
# UPDATE 2008/04/28     Ver.1.0.0
#        2008/05/19     Ver.1.0.1   SQL履歴作成機能の追加
#        2008/06/03     Ver.1.0.2   履歴からの実行機能および取得データエクスポート機能の追加
#        2008/06/07     Ver.1.0.3   取得結果をデータグリッドビューに表示できるようにする
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Execute-Query([string]$ExportXmlFile, [switch]$View, [switch]$History)
{
    if ( $History )
    {
        #履歴からの実行(Ver.1.0.2 )
        $XmlFile = "$([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle\History.xml"
        $SqlHis = View-History $XmlFile
      
        if ($SqlHis -eq $Null) { return }
    }
    
    if ( $SqlHis.Length -gt 0 )
    {
        $strSQL = $SqlHis
    }
    else
    {
        Write-Host "SQLを入力してください。" -foregroundcolor Yellow
        Write-Host "`";`"で入力を終了し、実行します。" -foregroundcolor Yellow
        
        #複数行のQueryStringを受け取る
        $strSQL = Read-MultiLine
    }
    
    #履歴の作成(Ver.1.0.1)
    Write-SqlHistory $strSQL
    
    #QueryStringを実行する
    $dtSet = Execute-QueryString $strSQL
    if ( $dtSet.Tables.Count -gt 0 )
    {
        #DataGridViewへの表示(Ver.1.0.3)
        if ( $View ) { View-Table $dtSet.Tables[0] }
        else {
            #format-tableコマンドレットでデータを表示
            $dtSet.Tables[0].Rows | format-table
        }
    }
    
    #取得データをXMLにエクスポート(Ver.1.0.2)
    if ( $ExportXmlFile.Length -gt 0 )
    {
        $dtSet.WriteXml($ExportXmlFile);
    }
}

開発ポイント

Execute-Query関数を呼び出すときに、パラメータ View を指定することで取得結果をデータグリッドビューへ表示することが可能になります。

パラメータViewはスイッチパラメータを使用しており、実行時に View パラメータが指定されると、変数$ViewがTrueになる性質を利用して、前回作成したView-Table関数を呼ぶように作成してあります。

使用方法

PS > Execute-Query -View
select * from emp;

これを実行すると、下記のようになります。

また、この関数は Histroy パラメータと同時に指定可能なので

PS > Execute-Query -View -History
select * from emp;

のように入力とすると

上図が表示され、この画面で[選択]ボタンを押すと

選択したSQLの実行結果が、データグリッドビューにが表示されます。

Saturday, June 07, 2008 10:31:53 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Friday, June 06, 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もどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る。終端判定を1文字以上でも行えるよう見直し。
SQL*PLUSもどきを作る7 Disconnect 切断処理

SQL*PLUSもどきを作る8

Write-SqlHistory SQL実行履歴の保存
SQL*PLUSもどきを作る6(改訂版) Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する。SQL実行履歴作成機能の追加。

SQL*PLUSもどきを作る9

View-History SQL履歴からの実行機能作成

SQL*PLUSもどきを作る6(改訂版2)

Execute-Query その9で作成した機能を組み込み、さらにXMLエクスポート機能を付加。

の続きです。

SQLを実行する関数 Execute-Queryをさらにカスタマイズして、SQLの実行結果をDataGridViewに表示する機能を追加したいと思います。

これを実現するためにView-Tableという関数を作成しました。

今回はこの関数について説明したい思います。この関数をExecute-Query関数から呼び出す部分は次回説明したいと思います。

この関数の実行結果は下記のようになります。

このようにデータグリッドビューに表示することによって、SQL文を書き直すことなく取得結果をソートすることが可能となります。

今回作成した関数は下記の通りです。

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
#===============================================================================
# View-DataSet: DataTableをデータグリッドへ表示する
#
# UPDATE: 2008-06-04 Ver.1.0.0
# 使用例
#   PS > View-Table [DataTable]
#
# copyright HIRO's.NET(http://hiros-dot.nte/)
#===============================================================================
function global:View-Table
{
    Param([System.Data.DataTable]$dtTbl)

    #===== Formの作成 =====
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "SQL実行結果"
    $form.Width = 500
    $form.Height = 400
    
    #===== DataGridViewの作成 =====
    $dgvXML = New-Object System.Windows.Forms.DataGridView
    $dgvXML.Dock = [System.Windows.Forms.DockStyle]::Fill
    $dgvXML.DataSource = $dtTbl
    $dgvXML.ReadOnly = $True
    $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()
}

開発ポイント

・パラメータはデータテーブル

呼び出し元のExecute-Query関数は、SQLの実行結果をデータセットに取り出します。

この関数では、そのデータセット内に作成されたデータテーブルを引数として受け取っています。

データグリッドビューはDataSourceプロパティにデータテーブルをセットすると、データテーブルに含まれるデータを自動で表示してくれるのでコードが短く済んでいます。

次回は、Execute-Query関数に、今回作成したData-View-を組み込みます。

 

Friday, June 06, 2008 11:20:36 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, June 05, 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もどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る。終端判定を1文字以上でも行えるよう見直し。
SQL*PLUSもどきを作る7 Disconnect 切断処理

SQL*PLUSもどきを作る8

Write-SqlHistory SQL実行履歴の保存
SQL*PLUSもどきを作る6(改訂版) Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する。SQL実行履歴作成機能の追加。

SQL*PLUSもどきを作る9

View-History SQL履歴からの実行機能作成

の続きです。

 

SQL*PLUSもどきを作成する その9」でView-History 関数を作成しました。

これに伴い、SQLを実行する関数 Execute-Queryを変更し、View-History関数を使用できるようにしたいと思います。

#=========================================================================================
# Execute-Query: QueryStringを実行する
#
# UPDATE 2008/04/28     Ver.1.0.0
#        2008/05/19     Ver.1.0.1   SQL履歴作成機能の追加
#        2008/06/03     Ver.1.0.2   履歴からの実行機能および取得データエクスポート機能の追加
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Execute-Query([string]$ExportXmlFile, [switch]$History)
{
    if ( $History )
    {
        #履歴からの実行(Ver.1.0.2 )
        $XmlFile = "$([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle\History.xml"
        $SqlHis = View-History $XmlFile
      
        if ($SqlHis -eq $Null) { return }
    }
    
    if ( $SqlHis.Length -gt 0 )
    {
        $strSQL = $SqlHis
    }
    else
    {
        Write-Host "SQLを入力してください。" -foregroundcolor Yellow
        Write-Host "`";`"で入力を終了し、実行します。" -foregroundcolor Yellow
        
        #複数行のQueryStringを受け取る
        $strSQL = Read-MultiLine
    }
    
    #履歴の作成(Ver.1.0.1)
    Write-SqlHistory $strSQL
    
    #QueryStringを実行する
    $dtSet = Execute-QueryString $strSQL
    if ( $dtSet.Tables.Count -gt 0 )
    {
        #format-tableコマンドレットでデータを表示
        $dtSet.Tables[0].Rows | format-table
    }
    
    #取得データをXMLにエクスポート(Ver.1.0.2)
    if ( $ExportXmlFile.Length -gt 0 )
    {
        $dtSet.WriteXml($ExportXmlFile);
    }
}

#エイリアス設定
Set-Alias -name EQS -value Execute-Query -scope "Global"

実は、おまけとして、SQL実行結果をXMLファイルにエクスポートする機能も付けてみました。

まずは、前回作成した関数を呼び出す方法について説明します。

関数の引数に [switch]$History というのがあるのですが(switchパラメータについてはこちらを参照)、このパラメータを指定して関数を実行するとSQL履歴実行フォームが表示される仕組みとなっています。

このフォームが閉じられると、履歴からSQLが選択されている場合には $SqlHisにそのSQLが代入されます。

この場合の実行方法は下記の通りです。

PS > eqs -History

次に、おまけのエクスポート機能ですが、この関数を

PS > eqs "C:\Work\SQL.xml"

のようにして、実行結果のエクスポート先を指定します。この場合は "C:\Work\SQL.xml" というファイルが作成されます。

このエクスポート機能は、先ほどのSQL履歴実行フォームとの併用が可能です。

併用する場合は

PS > eqs "C:\Work\SQL.xml" -History

のようにします。 これは、SQL履歴実行を行った後に、XMLエクスポートを行います。

 

Thursday, June 05, 2008 10:29:26 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Wednesday, June 04, 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もどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る。終端判定を1文字以上でも行えるよう見直し。
SQL*PLUSもどきを作る7 Disconnect 切断処理

SQL*PLUSもどきを作る8

Write-SqlHistory SQL実行履歴の保存
SQL*PLUSもどきを作る6(改訂版) Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する。SQL実行履歴作成機能の追加。

の続きです。

「SQL*PLUSもどきを作る その6(改訂版)」の関数 Exequte-Query ではSQLを実行して、結果をコンソールに表示することが可能です。

今回、この関数をカスタマイズして、Widows FormにSQL実行履歴を表示し、再実行できるようにしたいと思います。

実行イメージは下記の通りです。

SQL実行履歴を表示するための関数を下記のように作成しました。

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
#===============================================================================
# View-History: SQL実行履歴を表示し選択させる
#
# UPDATE: 2008-06-04 Ver.1.0.0
#
# 使用例
#   PS > View-History XMLファイルパス
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#===============================================================================
function global:View-History
{
    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
    [void]$dtSet.ReadXml($XmlFile)
    
    #===== Formの作成 =====
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "SQL実行履歴"
    $form.Width = 500
    $form.Height = 500
    
    #===== SplitContainerの作成 =====
    $splCont = New-Object System.Windows.Forms.SplitContainer
    $splCont.Orientation = [System.Windows.Forms.Orientation]::Horizontal
    $splCont.Dock = [System.Windows.Forms.DockStyle]::Fill
    $splCont.SplitterDistance = 300
    $form.Controls.Add($splCont)
    
    #===== ListViewの作成 =====
    $lsvHis = New-Object System.Windows.Forms.ListView
    $lsvHis.Dock = [System.Windows.Forms.DockStyle]::Fill
    $lsvHis.View = [System.Windows.Forms.View]::Details
    $lsvHis.Font = "MS ゴシック, 9pt"
    $lsvHis.FullRowSelect = $True
    [void]$lsvHis.Columns.Add("Date", 120)
    [void]$lsvHis.Columns.Add("SQL", 350)  
    $splCont.Panel1.Controls.Add($lsvHis)
    
    #データをリストビューに表示
    for ( $i = $dtSet.Tables[0].Rows.Count - 1; $i -ge 0; $i-- )
    {
      $itemx = New-Object System.Windows.Forms.ListViewItem
      $itemx.Text = $dtSet.Tables[0].Rows[$i]["UPDT"]
      [void]$itemx.SubItems.Add($dtSet.Tables[0].Rows[$i]["SQL"])
      [void]$lsvHis.Items.Add($itemx)
    }
    
    #===== TextBoxの作成 =====
    $txtHis = New-Object System.Windows.Forms.TextBox
    $txtHis.Dock = [System.Windows.Forms.DockStyle]::Fill
    $txtHis.Multiline = $True
    $txtHis.Font = "MS ゴシック, 9pt"
    $splCont.Panel2.Controls.Add($txtHis)
  
    #===== Panelの作成 =====
    $panel1 = New-Object System.Windows.Forms.Panel
    $form.Controls.Add($panel1)
    $panel1.Dock = [System.Windows.Forms.DockStyle]::Bottom
    $panel1.Height = 30
  
    #===== ListViewイベントの追加 =====
    $lsvHis.Add_SelectedIndexChanged({
      if ( $lsvHis.SelectedItems.Count -gt 0 )
      {
        $txtHis.Text = $lsvHis.SelectedItems[0].SubItems[1].Text
      }
    })
  
    #===== [選択]ボタンの作成 =====
    $btnSelect = New-Object System.Windows.Forms.Button
    $btnSelect.Location = New-Object System.Drawing.Point(324, 4)
    $btnSelect.Text = "選択"
    $btnSelect.anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right
    $btnSelect.Add_Click({
      $form.DialogResult = [System.Windows.Forms.DialogResult]::OK
      [void]$form.Close()
    })
    $panel1.Controls.AddRange($btnSelect)
  
    #===== [閉じる]ボタンの作成 =====
    $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.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
      [void]$form.Close()
    })
    $panel1.Controls.AddRange($btnClose)
    
    #===== Formを表示 =====
    if ($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK )
    {
      return $txtHis.Text.Trim()
    }
}

開発ポイント

1) Windows Formの作成

このフォームは、SplitContainerを配置して上下に分割し、上にリストビューを下にテキストボックスを配置しています。そのほかにはパネルを配置しており、その上に[選択]ボタンと[閉じる]ボタンをのせています。

2) 履歴の表示

この関数は、引数にXMLファイル(SQL実行履歴)のパスを受け取ります。

DataSetのReadXmlメソッドで、このXMLファイルを読み込みリストビューへ表示しています。

3) SQL選択時の処理

履歴リストで選択されたSQLはリストビューのSelectedIndexChangedを使用して、下に配置されてあるテキストボックスへ表示します。

4) [選択]ボタンクリック時の処理

選択ボタンが押されたらDialogResultをOKにしてフォームを閉じます。

このフォームはShowDialogメソッドを使用して表示されているので、DialogResultがOKだったときに、テキストボックスに表示されていたSQL文をreturnで返すようにしました。

この関数の作成に伴い、Execute-Query関数を変更する必要があるのですが、これについては次回説明したいと思います。

Wednesday, June 04, 2008 10:24:33 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Monday, May 19, 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*PLUSもどきを作る8

Write-SqlHistory SQL実行履歴の保存

の続きです。

前回、SQL実行履歴を保存する関数を作成しました。

今回は、SQL*PLUSもどきを作る6で作成した関数に、この機能を組み込みたいと思います。

とは、いっても一行追加するだけです。

 

#=========================================================================================
# Read-MultiLine: QueryStringを実行する
#
# UPDATE 2008/04/28		Ver.1.0.0
#        2008/05/19		Ver.1.0.1
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Execute-Query
{
	#複数行のQueryStringを受け取る
	$strSQL = Read-MultiLine
	
	#履歴の作成(Ver.1.0.1)
	Write-SqlHistory $strSQL
	
	#QueryStringを実行する
	$dtSet = Execute-QueryString $strSQL
	if ( $dtSet.Tables.Count -gt 0 )
	{
        #format-tableコマンドレットでデータを表示
        $dtSet.Tables[0].Rows | format-table
	}
}

#エイリアス設定
Set-Alias -name EQS -value Execute-Query -scope "Global"

これで、実行したSQLがXMLファイルに履歴として作成されるようになります。

Monday, May 19, 2008 5:03:30 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
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
Thursday, May 08, 2008

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)
SQL*PLUSもどきを作る その2(PowerShell Tips)
SQL*PLUSもどきを作る その3(PowerShell Tips) 
SQL*PLUSもどきを作る その4(PowerShell Tips) 
SQL*PLUSもどきを作る その5 改訂版(PowerShell Tips)
SQL*PLUSもどきを作る その6(PowerShell Tips)

の続きです。

今回は切断処理を行うDisconnect関数を作成しました。

とはいってもSQL*PLUSもどき(関数PSOracle)は非接続型を採用しているため、実際には切断処理は必要ありません。

しかし、PSOracle関数を実行して、動的に登録された関数やグローバル変数をいつまでも残しておくのは気持ち悪いため、Disconnect関数を作成し、それらを削除するようにしてみました。

#=========================================================================================
# Disconnect: 切断処理の実施
#
# UPDATE: 2008-05-08
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Disconnect
{
    $ret = Read-Host ($OracleConnInfo + " から切断します。よろしいですか?( Y/N )")
    if ( $ret -eq "N" )
    {
        return
    }
    
    #PSOracle用に登録したグローバル変数を削除
    Remove-Item variable:OracleDataSource
    Remove-Item variable:OracleUserID
    Remove-Item variable:OraclePassword
    Remove-Item variable:OracleConnInfo

    #Oracle専用スクリプトファイルを格納しているディレクトリの設定
    $OracleScriptPath = "$([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle"
    
    #存在するパス?
    if ( Test-Path $OracleScriptPath )
    {
        #PSOracle用に登録された関数の削除(長いので折り返しています。実際には1行        Get-ChildItem $OracleScriptPath -Include "*.ps1" -Recurse -Force | 
% { Remove-Item ("function:" + [System.IO.Path]::GetFileNameWithoutExtension($_.Fullname)) }
    }
    else
    {
        #実行可能なスクリプトがない場合は処理終了
        return
    }
}

使用方法ですが下記のように関数をコールするだけです。

PS > Disconnect

これで、PSOracle関連の関数は使用することができなくなります。

開発ポイント

変数と関数の削除

変数や関数を削除するにはRemove-Itemコマンドレットを使用します。

変数を削除するには Remove-Item Variable:変数名 とします。

たとえば $OracleDataSouurceを削除する場合は変数の$を取って

PS > Remove-Item variable:OracleDataSource

とします。

関数の削除も同様にして、Remove-Item function:関数名 とします。

PSOracleによって登録された関数のリストをどうやって取得するか悩みました。

登録した関数のリストを取得するいいアイディアが浮かばなかったので、邪道だとは思いましたが、ファイル名=関数名.ps1 としているので、ファイル名から拡張子を取ったものをRemove-Itemコマンドレットで削除するように記述し、関数の削除を行っています。

Thursday, May 08, 2008 4:32:32 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, May 01, 2008

このBlogはhttp://techbank.jp/hiroへもクロスポストで運営しているのですが、そちらの方でRead-MultiLineメソッドの終端判定に"EOF"という文字列を指定できるかという質問がありました。

この関数はSQL*PLUSもどきで使用することを想定していたので、当初は";"が入力されたら入力を打ち切るように作りました。

(これはSQL*PLUSで実行するコマンドは";"を終端文字として判定しているからです)

しかし、このRead-MultiLineメソッドは「SQL*PLUSもどき」以外でも使用可能な関数であるため、終端判定を1文字以上でも行えるよう見直してみました。

下記が改訂版の関数です。

#=========================================================================================
# Read-MultiLine: コマンドラインから複数行の入力を受け取る
#
# UPDATE 2008/04/24		Ver.1.0.0 
#        2008/05/01		Ver.1.0.1 終了判定文字に1文字以上の文字列を指定できるよう修正
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Read-MultiLine ( [string]$prompt, [string]$endChar = ";" ){
	if ($args[0] -eq "-?" )
	{
		Write-Host @"
名前:
        Read-MultiLine

概要:
        コマンドラインから複数行文字列を取得します。

構文:
        Read-MultiLine [-prompt] [-endChar]

使用方法:
        -------------------------- 例 1 --------------------------
        `$a = Read-MultiLine
        
        この例はコマンドラインから複数行を取得し行終端が";"の場合に読み取りを中止し結果を返します。
        入力の終了を判定する文字は";"が規定値です。
        
        -------------------------- 例 2 --------------------------
        `$a = Read-MultiLine -prompt "文字列を入力してください"
        
        この例はプロンプトに"文字列を入力してください"と表示した後に入力を受け付けます。
        
        -------------------------- 例 3 --------------------------
        `$a = Read-MultiLine -endChar "#"
        
        この例は入力の終了を判定する文字を"#"とします。
        ユーザー入力の行終端が"#"である場合に、入力を中断し結果を返します
        
        -------------------------- 例 4 --------------------------
        `$a = Read-MultiLine -endChar "EOF"
        
        この例は入力の終了を判定する文字を"EOF"とします。
        ユーザー入力の行終端が"EOF"である場合に、入力を中断し結果を返します
        
"@ -foregroundcolor Cyan
        return
	}
	if ( $prompt.Length -gt 0 ){ Write-Host ($prompt + ":") }
	
	while(1)
	{
		$ip += Read-Host
		if ($ip.SubString($ip.Length - $endChar.Length) -eq $endChar){ break; }
		else{$ip += "`n"}
	}
	#Write-Host $ip
	
	
	return $ip.Substring(0, $ip.Length - $endChar.Length)
}

whileの中のif文を

if ($ip.SubString($ip.Length-1,1) -eq $endChar)

から

if ($ip.SubString($ip.Length - $endChar.Length) -eq $endChar)

へ変更しました。

Thursday, May 01, 2008 10:18:03 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Tuesday, April 29, 2008

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)
SQL*PLUSもどきを作る その2(PowerShell Tips)
SQL*PLUSもどきを作る その3(PowerShell Tips) 
SQL*PLUSもどきを作る その4(PowerShell Tips)
SQL*PLUSもどきを作る その5(PowerShell Tips)

の続きです。

今回は、ユーザーが入力したQueryStringを実行し結果を表示する関数 Execute-Query を紹介します。

この関数は、SQL*PLUS同様、複数行にわたるQueryStringを実行し、結果を表示することができます。

ただし、SQL*PLUSのようにいきなりSELECT文を書き始めることはできず、

PS > Execute-Query SELECT文

のように入力する必要があります。

#=========================================================================================
# Execute-Query
: QueryStringを実行する
#
# UPDATE 2008/04/28 Ver.1.0.0
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Execute-Query { #複数行のQueryStringを受け取る $strSQL = Read-MultiLine #QueryStringを実行する $dtSet = Execute-QueryString $strSQL if ( $dtSet.Tables.Count -gt 0 ) { #format-tableコマンドレットでデータを表示 $dtSet.Tables[0].Rows | format-table } } #エイリアス設定 Set-Alias -name EQS -value Execute-Query -scope "Global"

開発ポイントですが、

複数行の入力を受け取ることができるようにSQL*PLUSもどきを作る その5(PowerShell Tips)で紹介した Read-MultiLine関数を使用しています。

入力を受け取った後は SQL*PLUSもどきを作る その3(PowerShell Tips)  で紹介したExecute-QueryString関数を実行し、結果を表示しています。

QueryStringを実行するたびに関数名 Execute-Query と入力するのは面倒なので、エイリアス設定をすることをおすすめします。(今回エイリアス名をEQSとしました)

使用方法および実行結果は下記の通りです。

PS > eqs
select * from
emp
;

         EMPNO ENAME          JOB                       MGR HIREDATE                  SAL COMM                   DEPTNO
         ----- -----          ---                       --- --------                  --- ----                   ------
          7369 SMITH          CLERK                    7902 1980/12/17 ...            800                            20
          7499 ALLEN          SALESMAN                 7698 1981/02/20 ...           1600 300                        30
          7521 WARD           SALESMAN                 7698 1981/02/22 ...           1250 500                        30
          7566 JONES          MANAGER                  7839 1981/04/02 ...           2975                            20
          7654 MARTIN         SALESMAN                 7698 1981/09/28 ...           1250 1400                       30
          7698 BLAKE          MANAGER                  7839 1981/05/01 ...           2850                            30
          7782 CLARK          MANAGER                  7839 1981/06/09 ...           2450                            10
          7788 SCOTT          ANALYST                  7566 1987/04/19 ...           3000                            20
          7839 KING           PRESIDENT                     1981/11/17 ...           5000                            10
          7844 TURNER         SALESMAN                 7698 1981/09/08 ...           1500 0                          30
          7876 ADAMS          CLERK                    7788 1987/05/23 ...           1100                            20
          7900 JAMES          CLERK                    7698 1981/12/03 ...            950                            30
          7902 FORD           ANALYST                  7566 1981/12/03 ...           3000                            20
          7777 HIRO

PS > eqs
select
*
from
emp
where JOB='CLERK';

         EMPNO ENAME          JOB                       MGR HIREDATE                  SAL COMM                   DEPTNO
         ----- -----          ---                       --- --------                  --- ----                   ------
          7369 SMITH          CLERK                    7902 1980/12/17 ...            800                            20
          7876 ADAMS          CLERK                    7788 1987/05/23 ...           1100                            20
          7900 JAMES          CLERK                    7698 1981/12/03 ...            950                            30

Tuesday, April 29, 2008 12:38:32 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)
SQL*PLUSもどきを作る その2(PowerShell Tips)
SQL*PLUSもどきを作る その3(PowerShell Tips) 
SQL*PLUSもどきを作る その4(PowerShell Tips)

の続きです。

今回紹介する関数は、コマンドラインから複数行の入力を取得するというものです。

Oracle用というわけではなく普段でも使用可能な関数です。

今回、SQL*PLUSもどきを作るにあたり、SQL文をどう入力させるかを検討しました。

SQL*PLUSでは複数行にわたるSQL文の入力が可能です。 しかしPowerShellでは複数行の入力を読み取るコマンドレットがないので、自作したというわけです。

下記が、複数行の入力を受け取るRead-MultiLine関数です。

#=========================================================================================
# Read-MultiLine: コマンドラインから複数行の入力を受け取る
#
# UPDATE 2008/04/24		Ver.1.0.0 
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Read-MultiLine ( [string]$prompt, [string]$endChar = ";" ){
	if ($args[0] -eq "-?" )
	{
		Write-Host @"
名前:
        Read-MultiLine

概要:
        コマンドラインから複数行文字列を取得します。

構文:
        Read-MultiLine [-prompt] [-endChar]

使用方法:
        -------------------------- 例 1 --------------------------
        `$a = Read-MultiLine
        
        この例はコマンドラインから複数行を取得し行終端が";"の場合に読み取りを中止し結果を返します。
        入力の終了を判定する文字は";"が規定値です。
        
        -------------------------- 例 2 --------------------------
        `$a = Read-MultiLine -prompt "文字列を入力してください"
        
        この例はプロンプトに"文字列を入力してください"と表示した後に入力を受け付けます。
        
        -------------------------- 例 3 --------------------------
        `$a = Read-MultiLine -endChar "#"
        
        この例は入力の終了を判定する文字を"#"とします。
        ユーザー入力の行終端が"#"である場合に、入力を中断し結果を返します
        
"@ -foregroundcolor Cyan
        return
	}
	if ( $prompt.Length -gt 0 ){ Write-Host ($prompt + ":") }
	
	while(1)
	{
		$ip += Read-Host
		if ($ip.SubString($ip.Length-1,1) -eq $endChar){ break; }
		else{$ip += "`n"}
	}
	#Write-Host $ip
	
	
	return $ip.Substring(0, $ip.Length - $endChar.Length)
}

この関数は、実行すると";"が入力されるまで、複数行に渡る文字列の読み取りを行います。

PS > $inp = Read-MultiLine
ABC
DEF
GHI;

下記のようにするとプロンプトを表示した後に入力を受けつけます。

PS > $inp = Read-MultiLine "入力してください"
入力してください:
This
is
Read-MultiLine
Command;

また、下記のようにすると終了判定文字を";"から"#"に変更することができます。

PS > $inp = Read-MultiLine -endChar "#"
ABC
DEF
GHI#
Tuesday, April 29, 2008 12:09:21 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [2]  |  Trackback
Monday, April 28, 2008

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)
SQL*PLUSもどきを作る その2(PowerShell Tips)
SQL*PLUSもどきを作る その3(PowerShell Tips) 

の続きです。

今回はSQL*PLUSのdescコマンドです。

describeコマンドを表現する関数を下記のように作ってみました。

#================================================================================================
# desc: Oracleのdescコマンド
#
# UPDATE: 2008-04-28    Ver.1.0.0
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#================================================================================================
function global:desc ([string]$TABLE_NAME) {
    $TBL = $TABLE_NAME.ToUpper()
    
    #descコマンドを実現させるためのSQL文作成
    $QueryString = "SELECT "
    $QueryString += "COLUMN_ID,"
    $QueryString += "COLUMN_NAME,"
    $QueryString += "DECODE(NULLABLE,'N','NOT NULL') NULLABLE,"
    $QueryString += "DATA_TYPE || '('  || "
    $QueryString += "DECODE(DATA_PRECISION, NULL, TO_CHAR(DATA_LENGTH),"
    $QueryString += "DECODE(DATA_SCALE,0,"
    $QueryString += "TO_CHAR(DATA_PRECISION),"
    $QueryString += "TO_CHAR(DATA_PRECISION) || ',' || TO_CHAR(DATA_SCALE))) || ')' DATATYPE "
    $QueryString += "FROM "
    $QueryString += "ALL_TAB_COLUMNS WHERE TABLE_NAME = '$TBL' ORDER BY COLUMN_ID"

    #DataSetに取得する
    $dtSet = (Execute-QueryString $QueryString)
    
    if ( $dtSet.Tables.Count -gt 0 )
    {
        #format-tableコマンドレットでデータを表示
        $dtSet.Tables[0].Rows | format-table
    }
}

使用方法はSQL*PLUSのdescコマンドと一緒で desc テーブル名/ビュー名 とします。

PS > desc emp

                    COLUMN_ID COLUMN_NAME   NULLABLE          DATATYPE
                    --------- -----------   --------          --------
                            1 EMPNO         NOT NULL          NUMBER(4)
                            2 ENAME                           VARCHAR2(10)
                            3 JOB                             VARCHAR2(9)
                            4 MGR                             NUMBER(4)
                            5 HIREDATE                        DATE(7)
                            6 SAL                             NUMBER(7,2)
                            7 COMM                            NUMBER(7,2)
                            8 DEPTNO                          NUMBER(2)

一応 More コマンドも使用可能で

PS > desc emp | more

と入力して1ページずつの表示も可能です。

リダイレクトも可能で

PS > desc emp > C:\Work\emp.txt

のようにすると 出力結果をC:\Work\emp.txtに作成します。

開発ポイントですが

descコマンドを実現するために、情報を ALL_TAB_COLUMNS から取得する。

結果の出力にformat-tableコマンドレットを使用する。

といったところでしょうか。出力をどうするかかなり悩みました。DataReaderで1行ずつ取得するとテキストの整形(列ごとにきれいに表示させる)処理を書く必要が出てくるためどうしたものかと考えていましたが、パイプでformat-tableコマンドレットへデータを渡したところきれいに表示されました。

見ていただけばわかるように、データセットにあるテーブルの行を丸投げしているだけです。

PowerShellってこういうところが非常によくできていますね。改めてすばらしいツールだと思いました。

Monday, April 28, 2008 10:06:36 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Sunday, April 27, 2008

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)
SQL*PLUSもどきを作る その2(PowerShell Tips)

の続きです。

今回はSelect文を実行して、取得した結果をDataSetで返す関数を紹介します。

 

#=========================================================================================
# Execute-QueryString: QueryStringを実行し結果をデータセットで返す
#
# UPDATE: 2008-04-27    Ver.1.0.0
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Execute-QueryString
{
    Param ( [string]$QueryString )

    #接続文字列の作成
    $ConnectionString = (Get-OracleConnectionString $OracleUserID $OraclePassword $OracleDataSource)
    #OracleConnectionの作成
    $OraConn = New-Object System.Data.OracleClient.OracleConnection($ConnectionString)
    #データセットの作成
    $dtSet = New-Object System.Data.DataSet
    #QueryStringを実行しデータを取得
    $OraDa = New-Object System.Data.OracleClient.OracleDataAdapter($QueryString, $OraConn)
    [void]$OraDa.Fill($dtSet)
    
    return $dtSet
}

この関数はSQL*PLUSもどきを作る その2(PowerShell Tips) で説明したGet-OracleConnectionString関数を使用して接続文字列を作成し、Oracleへ接続します。

このときの引数に与えているのはSQL*PLUSもどきを作る その1(PowerShell Tips)のPSOracle関数内で作成されたグローバル変数です。

OracleDataAdapterを使用して、QueryStringを実行し結果をDataSetへ格納します。

Sunday, April 27, 2008 9:29:48 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Friday, April 25, 2008

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)

の続きです。

今回は接続文字列を作成する関数 Get-OracleConnectionStirng関数を紹介します。

関数名が長いので任意のエイリアスを設定したり、直接関数名を変えてください。

関数を下記に示します。

#================================================================================================
# Get-OracleConnectionString: Oracle用接続文字列を作成する
#
# UPDATE: 2008-04-25 Ver.1.0.0
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#================================================================================================
function global:Get-OracleConnectionString([string]$UserID, [object]$Password, [string]$DataSource)
{
    if ($args[0] -eq "-?")
    {
        Write-Host @"
名前:
        Get-OracleConnectionString

概要:
        Oracle用接続文字列を作成します

構文:
        Get-OracleConnectionString [-UserID] [-Password] [-DataSource]

使用方法:
        `$ConnString = (Get-OracleConnectString "User" "Password" "ServerName")
"@ -foregroundcolor Cyan
        return
    }
    
    #パスワードがSecureString型の場合はString型にする
    if ( $Password -is [System.Security.SecureString] )
    {
        $ptr  = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
        $pass = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr);
    }
    else
    {
        $pass = $Password
    }
    
    #接続文字列を作成して返す
    return  "Data Source=$DataSource;User ID=$UserID;Password=$pass;Integrated Security=no;"
}

使用方法は

PS > Get-OracleConnectionString scott tiger OraSvr10g
Data Source=OraSvr10g;User ID=scott;Password=tiger;Integrated Security=no;

関数名の後に「ユーザー名」「パスワード」「接続先を」指定すると接続先文字列を返します。

この接続文字列はOracleClient用のものが作成されます。

また引数の「パスワード」ですが、これにはString型またはSecureString型を渡します。

SecureString型が渡された場合は、関数内部でString型に戻して接続文字列を作成します。

*で伏せられたパスワード文字列も、この関数を通して接続文字列を返すと、上記のようにパスワードが丸見えになりますので使用する場合は注意してください。

今回紹介した関数は SQL*PLUSもどきを作る その1(PowerShell Tips) の中で使用していますので、興味がある方は参考にしてみてください。

Friday, April 25, 2008 9:46:03 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, April 24, 2008

SQL*PLUSもどきを作る その1(PowerShell Tips) で紹介した関数PSOracleの説明です。

まずは使用方法ですが、コマンドラインで

PS > PSOracle

と入力します。すると「ユーザー名「パスワード」「接続先」を聞かれるので順に入力します。

ユーザー名を入力してください: scott
パスワードを入力してください: *****
接続先を入力してください: server01

Oracle 8i Release 8.1.7.1.1 -Production

うまく接続ができると、接続先のサーバーのバージョンが表示されます。

ちなみに、コマンドラインで

PS > PSOracle -?

とすると使用方法が表示されます。

では、順を追って解説していきたいと思います。

1.PSOracle用ライブラリの読み込み

PSOracle関数を呼び出すと、最初にMy Documents\WindowsPowerShell\Oracle フォルダ内にある*.ps1ファイルを読み込み、PowerShellに関数を登録します。

こうすることで、PSOracleが実行されたときに、必要な関数を登録します。

SQL*PLUSもどきで必要な関数を*.ps1ファイル化して、このフォルダに置くことで、PSOracleを拡張していくことを可能にしてます。

動的にPowerShellに関数を登録するには呼び出し演算子(&)を使用して登録しています。

2.ユーザーからの情報取得

ユーザーから情報を取得するにはRead-Hostコマンドレットを使用します。

パスワードに関しては、入力した文字が丸見えでは困るので -assecurestring パラメータを付加しています。こうすることで入力した文字は*で表示されます。

3.グローバル変数の作成

PSOracleの関数を抜けてしまうと、ユーザーから取得した接続先情報が失われてしまうのでグローバル変数に登録します。

グローバル変数の作成は Set-Variableコマンドレットを使用して -Scopeパラメータで"Global"を使用します。

ここで作成した変数に、ユーザーから取得した情報をセットすることで、関数を抜けた後でも再利用できるようにしています。

4.Oracleへ接続する

Oracleへの接続はOracleClientを使用しています。

PSOracleが読み込まれたときに、System.Data.OracleClientをロードして使用可能にしています。

接続文字列は、自作関数 Get-OracleConnectionString(次回説明予定)で作成しています。この接続情報を元にOracleへ接続してサーバ情報を取得するSQL文を実行しデータセットへ結果を取得します。

5.エラートラップ

接続時のエラートラップは trap {} で行います。

これはVB.NETやC#でいうところのcatchの部分に相当します。 VB.NETやC#を扱っているとtry部分がないのが気になるところです。 関数内で例外が発生すると trap 部分が処理されます。

 

Thursday, April 24, 2008 8:38:24 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Wednesday, April 23, 2008

自分が勤務している会社は、データベースがOracleなのでSQL*PLUSをよく使用します。

SQL*PLUSってCMD.EXEやPowerShellからでも

C:\Work> sqlplus

って入力すれば使用できますよね?

で、最近はCMD.EXEよりはPowerShellを使用しているので、PowerShellからSQL*PLUSを呼び出しています。

sqlplus[Enter]と入力して sqlplusを使用するとPowerShellのコマンドレットが使えなくなります。(sqlplusを起動させているので当然なのですが)

自分は欲張りなので、SQL*PLUSを起動しつつもPowerShellも使いたいと思いました。そうすれば取得結果をリダイレクトしてファイルに落としたり、Window Formへデータ渡してみたりといろいろと応用が利きそうです。

ということで、PowerShellで動くSQL*PLUSもどきを作ってみたいと思います。

とはいっても、descコマンドと、SQLの実行ができることだけを目標にしています。

今回は、SQL*PLUSもどきの入り口部分を作ってみました。

関数名はPSOracle(PowerShell で Oracleの略)です。

実行すると、ユーザー名、パスワード、接続先を聞かれるので、順に入力すると、

1.PSOracle用のその他のライブラリ(関数ファイル)をPowerShellへ登録
2. グローバル変数へ接続先情報の登録
3.実際に接続してOracleサーバーのバージョンの表示を行います

以下が関数本体(PSOracle.ps1)です。

#===============================================================================
# Get-OracleConnectionString: PowerShellで独自のOracle関連スクリプトを使用可能にする
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#===============================================================================

#Assemblyのロード
[void][reflection.assembly]::LoadWithPartialName("System.Data.OracleClient")

function Global:PSOracle
{
        if ($args[0] -eq "-?")
        {
                Write-Host @"
名前:
        PSOracle

概要:
        PowerShellで独自のOracle関連スクリプトを使用可能にします

構文:
        PSOracle

使用方法:
        PS > PSOracle
        ユーザー名を入力してください: USERNAME
        パスワードを入力してください: PASSWORD
        接続先を入力してください: OracleServer
"@ -foregroundcolor Cyan
        return
        }

    #Oracle専用スクリプトファイルを格納しているディレクトリの設定
    $OracleScriptPath = $([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle"

    #存在するパス?
    if ( Test-Path $OracleScriptPath )
    {
        #呼び出し演算子(&)を使用して関数を登録
        Get-ChildItem $OracleScriptPath -Include "*.ps1" -Recurse -Force | % { &($_.Fullname); }
    }
    else
    {
        #実行可能なスクリプトがない場合は処理終了
        return
    }

    #ユーザーから接続先情報を取得する
    $UserID = Read-Host "ユーザー名を入力してください"
    $Password = Read-Host "パスワードを入力してください" -assecurestring
    $DataSource = Read-Host "接続先を入力してください"

    #変数の作成
    Set-Variable -Scope "Global" -Name "OracleDataSource" -value $DataSource 
    Set-Variable -Scope "Global" -Name "OracleUserID"     -Value $UserID;
    Set-Variable -Scope "Global" -Name "OraclePassword"   -Value $Password;
    Set-Variable -Scope "Global" -Name "OracleConnInfo"   -Value "$UserID@$DataSource";

    $strSQL = "SELECT PRODUCT || 'Release ' || VERSION FROM product_component_version Where UPPER(PRODUCT) LIKE 'ORACLE%'"

    $ConnectionString = (Get-OracleConnectionString $UserID $Password $DataSource)
    $OraConn = New-Object System.Data.OracleClient.OracleConnection($ConnectionString)
    $dtSet = New-Object System.Data.DataSet
    $OraDa = New-Object System.Data.OracleClient.OracleDataAdapter($strSQL, $OraConn)
    [void]$OraDa.Fill($dtSet)

    if ( $dtSet.Tables.Count -gt 0 )
    {
        Write-Host ("`n" + $dtSet.Tables[0].Rows[0][0].ToString() + " - Production`n")
    }

    trap [System.Data.OracleClient.OracleException]
    {
        Write-Error ("接続に失敗しました。")
        break;
    }

    trap
    {
        Write-Error ($Error[0].Exception);
        break;
    }
}

詳細については次回説明したいと思います。

Wednesday, April 23, 2008 8:47:35 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Monday, March 31, 2008

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

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

でOracleデータベースからデータを取得し、XMLファイルへ保存する関数を紹介しました。
今回は、これを改善し、

  • 取得したデータをWinodwsフォームのDataGridViewへの表示
  • [XMLへ保存]ボタンが押されたら、ファイル保存ダイアログを表示し、任意の名前を付けて保存
    ができるようにしてみました。

Export-OracleDataXml2.ps1

#===============================================================================
# Export-OracleDataXml2: データを取得してXMLファイルへ保存する(Oracle)
#
# 使用例
#   PS > Export-OracleDataXml
#   PS > DataSource: データソース名
#   PS > User ID: ユーザーID
#   PS > Password: パスワード
#   PS > Query String: クエリ文字列
#
# copyright HIRO's.NET(http://hiros-dot.net.com/)
#===============================================================================
function global:Export-OracleDataXml2
{
  #===== 必要情報をユーザーから取得する =====
  $DataSource = Read-Host "Data Source"
  $UserID = Read-Host "User ID"
  $Password = Read-Host "Password" -assecurestring
  $QueryString = Read-Host "Query String"
  
  #===== newpopsさんのblog参照 http://d.hatena.ne.jp/newpops/20050923/p1 =====
  #SecureStringからパスワード文字列を取得する
  $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
  $pass = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr)
  
  #===== Oracleからのデータ取得 =====
  [reflection.assembly]::LoadWithPartialName("System.Data.OracleClient")
  $ConnectionString = "Data Source=" + $DataSource + ";User ID=" + $UserID + ";Password=" + $Pass + ";Integrated Security=no;"
  $OraConn = New-Object System.Data.OracleClient.OracleConnection($ConnectionString)
  $dtSet = New-Object System.Data.DataSet
  $OraDa = New-Object System.Data.OracleClient.OracleDataAdapter($QueryString, $OraConn)
  $OraDa.Fill($dtSet)
  
  #===== Formの作成 =====
  [reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
  $form = New-Object System.Windows.Forms.Form
  $form.Text = $DataSource + "@" + $UserID
  $form.Width = 500
  $form.Height = 400

  #===== DataGridViewの作成 =====
  $dgvOracle = New-Object System.Windows.Forms.DataGridView
  $dgvOracle.Dock = [System.Windows.Forms.DockStyle]::Fill
  $dgvOracle.DataSource = $dtSet.Tables[0]
  $form.Controls.Add($dgvOracle)
  
  #===== Panelの作成 =====
  $panel1 = New-Object System.Windows.Forms.Panel
  $form.Controls.Add($panel1)
  $panel1.Dock = [System.Windows.Forms.DockStyle]::Bottom
  $panel1.Height = 30

  #===== [XMLへ保存]ボタンの作成 =====
  $btnExport = New-Object System.Windows.Forms.Button
  $btnExport.Location = New-Object System.Drawing.Point(324, 4)
  $btnExport.Text = "XMLへ保存"
  $btnExport.anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right
  $btnExport.Add_Click(
  {
    #===== ファイル保存ダイアログを作成 =====
    $dlgSave = New-Object System.Windows.Forms.SaveFileDialog
    $dlgSave.DefaultExt = "XML"
    $dlgSave.Filter = "XMLファイル(*.xml)|*.xml"
    if ( $dlgSave.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK )
    {
      #===== データを保存する =====
      $dtSet.WriteXml($dlgSave.Filename)
    }
  })
  $panel1.Controls.Add($btnExport)
  
  #===== [閉じる]ボタンの作成 =====
  $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()
}

 

実行結果は、下記のとおりです。

 

今回のポイント
・Windows フォームを作成する
VB.NETやC#で開発をされている方は、ソースを見ると何となくわかると思います。


**VB.NET**

Dim form As New Form()


**C#**

Form form = new Form();


**PowerShell**

$form = New-Object System.Windows.Forms.Form


でフォームのインスタンスを作成します。

・各コントロールの作成とフォームへの配置
コントロールを作成してフォームへ配置するには

$control = New-Object System.Windows.Forms.コントロール


のように記述してコントロールを作成して

$form.ControlAdd($control)


としてフォームへ配置します。
今回、ボタンはパネル上に配置したので

$panel1.Controls.Add($btnExport)


のようになっています。

・ボタンのクリックイベント


ボタンのクリックイベントは

$button.Add_Click({ここに処理したいスクリプトを記述})


のように記述します。

Monday, March 31, 2008 2:48:36 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

Theme design by Jelle Druyts

Pick a theme: