あるSEのつぶやき・改

ITやシステム開発などの技術に関する話題を、取り上げたりしています。

PowerShell, Access データベースに ADO.NET の名前付きパラメータでデータを読み込む

PowerShell を使って Access のデータベースにアクセスするには、実行環境や接続文字列に注意点があります。この点の詳しい内容は以下の記事を参照してください。

.NET Framework の ADO.NET で、Access データベースに名前付きパラメータを使用してテーブルのデータを取得するサンプルを提示します。ADO.NET を使用しているので、SQL Server も同様にアクセスできると思います。

名前付きパラメータはパラメータクエリやプリペアードステートメントとも呼ばれますね。

詳細はコメントを付けてあるので分かると思いますが、スクリプトと同じディレクトリにある Access のデータベースファイル (test.mdb or test.accdb) にアクセスし、以下のテーブルを取得します。

  • テーブル名:tblUsers
  • フィールド情報
    • USER_ID (varchar (255))
    • USER_NAME (varchar (255))

ADO との違いは COM を経由していないので COM 参照の解放の手間がないといったところでしょうか。また、パラメータに名前を付けることができるので、コーディングでの間違いが少ないといった点でしょうか。

あと、DataReader ではなく DataTable を使用する方法がありますが、個人的な趣味で DataReader を使用しています。

サンプルスクリプトは以下のようになります。

#
#  PowerShell から ADO.NET の名前付きパラメータでデータを読み込む
#

# スクリプトのカレントディレクトリを取得
$path = Split-Path $MyInvocation.MyCommand.Path -Parent

# スクリプトのカレントディレクトリのデータベースパスを作成
$path = Join-Path $path "test.mdb" # test.accdb も可


# 拡張子によって接続文字列を切り替える

# MDB 形式の場合
if (([System.IO.Path]::GetExtension($path)) -eq ".mdb") {
  $connectionString = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = $path"

# ACCDB 形式の場合
} elseif(([System.IO.Path]::GetExtension($path)) -eq ".accdb") {
  $connectionString = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source = $path"

# 上記以外は例外をスロー
} else {
  throw New-Object System.Exception("Access 拡張子エラー")
}

# データベースの接続を宣言
$con = New-Object -TypeName System.Data.OleDb.OleDbConnection $connectionString

# 名前付きパラメータ付き SQL を宣言
$sql = "SELECT * FROM tblUsers WHERE USER_ID = @ID"

# コマンドを宣言
$command = New-Object -TypeName System.Data.OleDb.OleDbCommand $sql, $con

# コマンドにパラメータの値を設定
[void]$command.Parameters.AddWithValue("@ID", "003")

# 接続をオープン
$con.Open()

# データを読み込み
$reader = $command.ExecuteReader()

# 1件しかないがレコードの最後までループする
While ($reader.Read()) {

  # 画面にレコードの値を出力する
  Write-Host $reader["USER_ID"].ToString()  ":"  $reader["USER_NAME"].ToString()

}

  
# DataReader を閉じる
$reader.Close()

# 接続を閉じる
$con.Close()