PowerShell

2019-09-23

OracleDatabaseにつなぎたい

WindowsPowerShellはWindowsOSでの動作であったため、WindowsにOracleClientが入っていればSystem.Data.OracleClient名前空間を使うことで
OracleDatabaseへの接続を行うことが出来た。
例えば以下のようなスクリプトで。

#sh(ruby){{

[Reflection.Assembly]::LoadWithPartialName("System.Data") | Out-Null;
[Reflection.Assembly]::LoadWithPartialName("System.Data.OracleClient") | Out-Null;

$strConn = "User Id=${username}; Password=${password}; Data Source=${hostname_and_port}/${service_name}";
$conn = New-Object -TypeName "System.Data.OracleClient.OracleConnection" -ArgumentList @($strConn);

}}

しかしPowerShellCoreでは、System.Data名前空間にOracleClientが入らなくなったし
そもそもOSにOracleClientが入っているかどうかが管理出来ない環境(例えばAWS Lambdaとか)での利用も想定しないといけない。

個人的にはOracleDatabaseはあんまりつかいたくないがしかし多くの社会の重要な基幹システムで使われていることも多いため避けては通れない。

そこでPowerShellCoreでOracleDatabaseを使う方法を調べた。

準備

NuGetパッケージの入手

OracleさんはちゃんとNuGetパッケージを用意されていたのでこれを使う。
https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core/

NuGet運用がちゃんと整っていない場合

NuGetの利用環境がちゃんと整っていなかったり、そもそもNuGetって何?という状況の場合には、.nugetパッケージをダウンロードしzip展開して得られたDLLを使う。
NuGetパッケージ画面の右側メニューから"Download package"リンクをクリックし、.nugetファイルを手動でダウンロードしてくる。
https://www.nuget.org/api/v2/package/Oracle.ManagedDataAccess.Core/2.19.31

使い方

こちらにOracleManagedDataAccessの使い方があるので、このようにコードを書く。
https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/dotnet/ODPNET_Core_get_started/index.html

PowerShellで性能を求めない汎用的な関数だとこんな感じ

MyDbiCore.psm1

#sh(ruby){{
$Local:__psscriptroot = $PSScriptRoot;



Add-Type -AssemblyName "System.Collections";



function New-DbiCoreConnectionString() {
Param(
[Parameter(Mandatory = $true, Position = 1)]
[string] $UserId,

[Parameter(Mandatory = $true, Position = 2)]
[string] $Password,

[Parameter(Mandatory = $true, Position = 3)]
[string] $Server,

[Parameter(Mandatory = $true, Position = 4)]
[string] $ServiceName
);

return "User Id=${UserId};Password=${Password};Data Source=${Server}/${ServiceName}";
}
Export-ModuleMember -Function "New-DbiCoreConnectionString";



function Open-DbiCoreConnection() {
Param(
[Parameter(Mandatory = $true, Position = 1)]
[string] $ConnectionString,

[Parameter(Mandatory = $false)]
[switch] $EnableKeepAlive = $false
);

$asm = @($__psscriptroot, "lib", "netstandard2.0", "Oracle.ManagedDataAccess.dll") -join [IO.Path]::DirectorySeparatorChar;
if(Test-Path -Path $asm) {
Add-Type -Path $asm;
} else {
Write-Host -Object $asm;
throw (New-Object -TypeName "System.Exception");
}

Add-Type -AssemblyName "System.Data";
$conn = New-Object -TypeName "Oracle.ManagedDataAccess.Client.OracleConnection" -ArgumentList @($ConnectionString);

# TO SET KEEPALIVE
if($conn.State -ne [System.data.ConnectionState]::Closed) {
$conn.Close();
}
if($EnableKeepAlive) {
$conn.KeepAlive = $true;
}

# OPEN FINALLY
if($conn.State -eq [System.Data.ConnectionState]::Closed) {
$conn.Open();
}

return $conn;
}
Export-ModuleMember -Function "Open-DbiCoreConnection";



function Close-DbiCoreConnection() {
Param(
[Parameter(Mandatory = $true, Position = 1)]
[object] $Connection
);

$Connection.Close();
$Connection.Dispose();
return;
}
Export-ModuleMember -Function "Close-DbiCoreConnection";



function Invoke-DbiCoreSqlStatement() {
Param(
[Parameter(Mandatory = $true, Position = 1)]
[object] $Connection,

[Parameter(Mandatory = $true, Position = 2)]
[string] $Statement
);

$cmd = $Connection.CreateCommand();
$cmd.CommandText = $Statement;

$r = $cmd.ExecuteReader();
$nFields = $r.FieldCount;
$names = New-Object -TypeName "string[]" -ArgumentList @($nFields);
$types = New-Object -TypeName "string[]" -ArgumentList @($nFields);
$data = New-Object -TypeName "System.Collections.ArrayList";
for($i = 0; $i -lt $nFields; ++$i) {
$names[$i] = $r.GetName($i);
$types[$i] = $r.GetFieldType($i).FullName;
}

while($r.Read()) {
$datum = New-Object -TypeName "System.Collections.ArrayList" -ArgumentList @($nFields);
for($i = 0; $i -lt $nFields; ++$i) {
switch($types[$i]) {
"System.Decimal" { $datum.Add($r.GetDecimal($i)) | Out-Null; }
"System.String" { $datum.Add($r.GetString($i)) | Out-Null; }
default { throw ([System.NotImplementedException]::new()); }
}
}
$data.Add($datum) | Out-Null;
}

$r.Close();
$cmd.Dispose();

return @{
"FieldCount" = $nFields;
"RecordCount" = $data.Count;
"Names" = $names;
"FieldTypes" = $types;
"Data" = $data;
};
}
Export-ModuleMember -Function "Invoke-DbiCoreSqlStatement";

}}

(psm1と同じディレクトリから見てlib/netstandard2.0/Oracle.ManagedDataAccess.dllに入手したDLLを置く必要あり)

サンプル

#sh(ruby){{
Import-Module -Name MyDbiCore;

$constr = New-DbiCoreConnectionString -Username "OREORE" -Password "ORENO_PASSWORD" -Server "ORENO-HOST" -ServiceName "OREOREDB";
$con = Open-DbiCoreConnection -ConnectionString $constr;

$res = Invoke-DbiCoreSqlStatement -Connection $con -Statement "SELECT 1 PING FROM DUAL";
Write-Host -Object $res.Data;

Close-DbiCoreConnection -Connection $con;
$con = $null;
}}


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-09-26 (木) 03:17:36