3.13 LOBサポート
ODP.NETは、ラージ・オブジェクト(LOB)データ型にアクセスして操作するための簡単かつ最適な方法を提供します。
注意:
SecureFilesは既存のODP.NET LOBクラスとともに使用できます。
この項の内容は次のとおりです。
3.13.1 ラージ・キャラクタ・データ型とラージ・バイナリ・データ型
Oracle Databaseは、ラージ・キャラクタ・データ型とラージ・バイナリ・データ型をサポートしています。
ラージ・キャラクタ・データ型
-
CLOB- キャラクタ・データを4GBまで格納できます。 -
NCLOB- Unicode各国語キャラクタ・セット・データを4GBまで格納できます。
ラージ・バイナリ・データ型
3.13.2 Oracle Data Provider for .NET LOBオブジェクト
ODP.NETでは、LOBデータを操作するために、OracleBFile、OracleBlobおよびOracleClobの3つのLOB用オブジェクトが提供されます。
表3-19は、特定のOracle LOBタイプに使用するのに適したODP.NETオブジェクトを示しています。
表3-19 ODP.NET LOBオブジェクト
| Oracle LOB型 | ODP.NET LOBオブジェクト |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
ODP.NET LOBオブジェクトは、OracleDataReaderで適切な型指定アクセッサをコールするか、適切なバインド・タイプのコマンド実行で、出力パラメータとして取得できます。
ODP.NET LOBオブジェクトはすべて、汎用的なStream操作を実行するために.NET Streamクラスから継承されます。LOBデータ(BFILEタイプを除く)は、Writeなどのメソッドを使用することで、ODP.NET LOBオブジェクトを使用して更新できます。読取りおよび書込み操作が実行されている場合、LOBオブジェクトのデータはキャッシュされません。このため、ReadまたはWriteの各要求は、データベース・ラウンドトリップを発生させます。OracleClobオブジェクトはReadメソッドをオーバーロードして、CLOBからデータを読み取る2つの方法を提供します。byte[]をバッファとして取得するReadメソッドは、Unicodeバイト配列としてCLOBデータを移入します。char[]をバッファとして取得するReadメソッドは、Unicode文字を移入します。
OracleBFileオブジェクトには拡張機能もあります。OracleBFileオブジェクトは、データが読み込まれる前に、OpenFileメソッドを使用して明示的にオープンする必要があります。以前にオープンしたBFILEをクローズするには、CloseFileメソッドを使用します。
ODP.NET LOBオブジェクトはすべて接続済のオブジェクトで、存続中は接続している必要があります。LOBオブジェクトに関連付けられた接続がクローズすると、LOBオブジェクトは使用できなくなり、処理が必要になります。
ODP.NET LOBオブジェクトが型指定アクセッサによってOracleDataReaderオブジェクトから取得される場合、Connectionプロパティは、OracleDataReaderオブジェクトで使用される同じOracleConnectionオブジェクトへの参照を使用して設定されます。LOBオブジェクトが出力パラメータとして取得される場合、Connectionプロパティは、OracleCommandオブジェクトで使用される同じOracleConnectionプロパティへの参照を使用して設定されます。一時LOBを作成するためにODP.NET LOBオブジェクト・コンストラクタを起動させることで、LOBオブジェクトが取得される場合、Connectionプロパティは、コンストラクタで指定されたOracleConnectionオブジェクトへの参照を使用して設定されます。
ODP.NET LOBオブジェクトのConnectionプロパティは読取り専用であり、存続中は変更できません。また、ODP.NET LOBタイプ・オブジェクトは、ODP.NET LOBオブジェクトで参照される同じOracleConnectionのコンテキスト内でのみ使用できます。たとえば、ODP.NET LOBのConnectionプロパティは、ODP.NET LOBオブジェクトがOracleCommandのパラメータである場合、OracleCommandオブジェクトと同じ接続を参照する必要があります。それ以外の場合、ODP.NETはコマンドの実行時に例外を発生させます。
関連項目:
Oracle Database 10g LOBの詳細とその使用方法は、Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイドを参照
3.13.3 DataSetを使用したLOBの更新
BFILEデータおよびBLOBデータは、byte配列としてDataSetに格納され、CLOBデータおよびNCLOBデータは、stringとして格納されます。他のタイプも同様に、OracleDataAdapterオブジェクトを使用して、SQLの自動生成にOracleCommandBuilderを使用することで、LOBデータの変更を入力および更新できます。
Oracle LOB列には、最大4GBのデータを格納できます。LOBデータがDataSetにフェッチされると、DataSetがLOB列に保持できるLOBデータの実際の量は、.NET文字列タイプの最大サイズ(2GB)に制限されます。このため、2GBより大きいLOBデータをフェッチする場合、ODP.NET LOBオブジェクトを使用してデータの損失を防ぐ必要があります。
3.13.4 OracleCommandおよびOracleParameterを使用したLOBの更新
LOB列を更新するには、LOBデータをSQL文、無名PL/SQLブロックまたはストアド・プロシージャのパラメータとしてバインドします。パラメータ値は、NET Frameworkタイプ、ODP.NETタイプまたはODP.NET LOBオブジェクト・タイプとして設定できます。たとえば、.NET文字列データをOracle9i以降のデータベースのLOB列に挿入する場合、そのパラメータをOracleDbType.Varchar2としてバインドできます。値がOracleClobオブジェクトに設定されているパラメータの場合、パラメータをOracleDbType.Clobとしてバインドする必要があります。
3.13.5 ODP.NET LOBオブジェクトを使用したLOBの更新
Oracle BFILEは更新できないため、OracleBFileオブジェクトでBFILE列を更新することはできません。
ODP.NET LOBオブジェクトを使用してLOBデータを更新するには、2つの要件を満たす必要があります。
-
LOB列を選択する前に、トランザクションを開始する必要があります。
OracleTransactionCommitメソッドまたはRollbackメソッドが起動されたときにロックが解除されるように、コマンド実行の前にOracleConnectionでBeginTransactionメソッドを使用してトランザクションを開始する必要があります。 -
行ごとに、または結果セット全体の一部として、LOB列が存在する行をロックする必要があります。
-
結果セット全体のロック
SELECT文の最後にFORUPDATE句を追加します。コマンドの実行後、結果セット全体がロックされます。 -
行のロックには、2つのオプションがあります。
-
OracleDataReaderオブジェクトでOracleDataReaderの型指定アクセッサの1つ(GetOracleClobForUpdateまたはGetOracleBlobForUpdate)を起動して、現在の行がロックされている間にODP.NET LOBオブジェクトを取得します。この方法では、結果セットに主キー、一意の列または
ROWIDが必要です。OracleDataReaderオブジェクトは行を一意に識別して、ロック用に再選択するためです。 -
RETURNING句でLOBを戻すINSERTまたはUPDATE文を実行します。
-
-
3.13.6 一時LOB
一時LOBは、BLOB、CLOBおよびNCLOBオブジェクトに対してインスタンス化できます。一時LOBを表すODP.NET LOBオブジェクトをインスタンス化するには、OracleClobまたはOracleBlobコンストラクタを使用します。
一時ODP.NET LOBオブジェクトは、次の目的に使用できます。
-
空または空ではないLOBデータを使用して、LOB列を初期化および移入します。
-
LOBタイプをSQL文、無名PL/SQLブロックまたはストアド・プロシージャへの入力パラメータとして渡します。
-
CopyTo操作において、2つのLOBオブジェクト間のデータ送信のソースまたは宛先として機能します。注意:
一時LOBはトランザクションを認識しません。コミット操作およびロールバック操作は、一時LOBで参照されるデータには影響しません。