Code Aquarium

minazoko's blog -*- 水底のブログ -*-

(#PowerShell) ODAC でOracle操作

PowerShellでODAC (Oracle Data Access Components)

PowerShellOracleで検索するといくつかサンプルコードが見つかります。
しかしどうも釈然としない、コレじゃない感。

すなわち

  • ADO.Netに含まれる System.Data.OracleClient や OleDbではなく、Oracle社の ODAC を使いたい
  • DbProviderFactoryを使って、抽象性・汎用性のあるコードを書きたい。
  • 例外安全性、リソース解放管理をちゃんとしたい。
  • 面倒なシステム設定などせずに直観的に分かりやすい方法論。レジストリ登録とか、machine.config を編集とかそういうのは無し。

そんなスクリプトを書きたい。書きました。

ODACによるQuery発行のサンプル。

オールインワンなので、少々長いです。
処理内容的にトランザクションは不要ですが、トランザクション利用も簡単だというサンプルを兼ねてます。UpdateしたらCommitしましょう。
Disposableオブジェクトを作ったら即Stackに突っ込む。かつ、finally節でStack内Objectを一括Dispose。Push-D のようなPushしてパススルーするFilterがあると オブジェクト生成してStack Pushするコードがスッキリします。
ODACロードに失敗した時は、System.Data.OracleClientを使います。こっちなら必ずあるはずなので。

リソース解放管理についてもう少し

Disposeしかしてない

Close等もちゃんとしたい向きは、別途Close用のStackを作るか、Release-Allを改造する方向で。

最後に一括リリースでいいのか?

例えば、Commandオブジェクトを大量に作るような場合、ある程度のところで都度解放したくなるかもしれません。そういう場合は、やっぱりライフサイクルでStackを分けて、適宜Releaseすればよいかなぁ。

難点

PowerShellはエラー発生時のメッセージが分かりにくい。もうちょっと何とかならないかな。
あと、PowerShell_ISEのインテリセンスが貧弱。メンバの多いクラスのオブジェクトは、キャストしておいた方が無難。

予想外だったこと

DataReaderを評価するといきなりフィールドデータの配列になってしまい面喰った。
Reader取得して、Read しつつwhileループして...ってやろうとすると逆に大変。素直にEnumeratorとして扱うほうがよさげ。