12 LOB APIの使用

BLOBCLOBおよびNCLOBデータ型の操作を実行するAPIは、表12-1を参照してください。これらの操作は、永続LOBインスタンスまたは一時LOBインスタンスに使用できます。これらはBFILEには適用されないことに注意してください。

関連項目:

これらの操作ごとに次の項目について説明します。

  • 前提条件では、各操作をコールする前に達成する必要がある依存性と、必要な条件について説明します。

  • 「使用上のノート」では、特定のプログラム環境またはデータ型に固有の情報など、実装に関するガイドラインを示します。

  • 「構文」では、サポートされているプログラム環境ごとに構文の参照先マニュアルを示します。

  • 「例」では、サンプルの実行に必要な設定タスクについて説明します。掲載されているデモ・ファイルは、$ORACLE_HOME/rdbms/demo/lobs/plsqlocivbおよびjavaという名前のサブディレクトリにあります。ドライバ・プログラムlobdemo.sql/plsqlにあり、ドライバ・プログラムlobdemo.c/ociにあります。

内容は次のとおりです。

12.1 サポートされている環境

表12-1に、この章で説明するAPIについてサポートされているプログラム環境を示します。第1列は、APIで実行される操作を示します。その他の列は、そのAPIがPL/SQL、OCI、OCCI、COBOL、Pro*C/C++およびJDBCでサポートされているかどうかに応じて、「はい」または「いいえ」となっています。

表12-1 LOB APIについてサポートされている環境

操作 PL/SQL OCI OCCI COBOL Pro*C/C++ JDBC

他のLOBへのLOBの追加について

はい

はい

いいえ

はい

はい

はい

文字セット・フォームの取得について

いいえ

はい

いいえ

いいえ

いいえ

いいえ

文字セットIDの取得について

いいえ

はい

いいえ

いいえ

いいえ

いいえ

チャンク・サイズの決定、関連項目: 「LOBへのデータの書込みについて」

はい

はい

はい

はい

はい

はい

2つのLOBの全体または一部の比較

はい

いいえ

いいえ

はい

はい

はい

BLOBからCLOBへの変換

はい

いいえ

いいえ

いいえ

いいえ

いいえ

CLOBからBLOBへの変換

はい

いいえ

いいえ

いいえ

いいえ

いいえ

LOBロケータのコピー

はい

はい

いいえ

はい

はい

はい

他のLOBへのLOBの全体または一部のコピー

はい

はい

いいえ

はい

はい

はい

LOBデータの表示について

はい

はい

いいえ

はい

はい

はい

等値: 2つのLOBロケータが等しいかどうかの確認

いいえ

はい

いいえ

いいえ

はい

はい

LOBの一部の消去について

はい

はい

いいえ

はい

はい

はい

LOBロケータが初期化されているかどうかの確認について

いいえ

はい

いいえ

いいえ

はい

いいえ

長さ: LOBの長さの取得

はい

はい

いいえ

はい

はい

はい

LOBへのBFILEデータのロード

はい

はい

いいえ

はい

はい

はい

BLOBへのBFILEデータのロードについて

はい

いいえ

いいえ

いいえ

いいえ

いいえ

CLOBまたはNCLOBへのBFILEデータのロード

はい

いいえ

いいえ

いいえ

いいえ

いいえ

LOB配列読取りについて

いいえ

はい

いいえ

いいえ

いいえ

いいえ

LOB配列書込み

いいえ

はい

いいえ

いいえ

いいえ

いいえ

OPENおよびCLOSEインタフェースを使用した永続LOBのオープン

はい

はい

はい

はい

はい

はい

オープン: LOBがオープンしているかどうかの確認

はい

はい

はい

はい

はい

はい

パターン: INSTRを使用したLOB内のパターンの有無の確認

はい

いいえ

いいえ

はい

はい

はい

LOBの一部の読取り(SUBSTR)

はい

いいえ

いいえ

はい

はい

はい

LOBからのデータの読取りについて

はい

はい

いいえ

はい

はい

はい

記憶域の制限、決定: サイズがTBのLOBの最大記憶域の制限

はい

いいえ

いいえ

いいえ

いいえ

いいえ

LOBデータの切捨てについて

はい

はい

いいえ

はい

はい

はい

WriteNoAppend、関連項目: 「LOBへの追加について」

いいえ

いいえ

いいえ

いいえ

いいえ

いいえ

LOBへのデータの書込みについて

はい

はい

はい

はい

はい

はい

12.2 他のLOBへのLOBの追加について

この操作では、あるLOBインスタンスを他のLOBインスタンスに追加します。

事前条件

LOBを他のLOBに追加する前に、次の条件を満たしている必要があります。

  • 2つのLOBインスタンスが存在していること。

  • 両方のインスタンスが同じ型であること(両方ともBLOB型、または両方ともCLOB型など)。

  • この操作には、永続LOBインスタンスまたは一時LOBインスタンスの任意の組合せを渡すことができます。

使用上のノート

永続LOB: PL/SQLのDBMS_LOBパッケージまたはOCIを使用する場合は、LOB値を更新する前にLOBを選択する行をロックする必要があります。SQL INSERT文およびUPDATE文は暗黙的に行をロックしますが、SQLプログラムおよびPL/SQLプログラムではSQL SELECT FOR UPDATE文を使用して、またOCIプログラムではOCI pinまたはlock関数を使用して明示的にロックできます。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次の例を実行するには、2つのLOBインスタンスを作成し、それを指定のAPPEND操作のコール時に渡す必要があります。

ここに示す例は、次のプログラム環境での例です。

  • PL/SQL (DBMS_LOBパッケージ): lappend.sql

  • OCI: lappend.c

  • Java(JDBC): lappend.java

関連項目:

12.3 文字セット・フォームの取得について

この項では、LOBインスタンスの文字セット・フォームを取得する方法について説明します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次の例では、外国語のテキスト(ad_fltextn)の文字セット・フォームを取得する方法について説明します。

この機能はOCIでのみ使用可能です。

  • OCI: lgetchfm.c

12.4 文字セットIDの取得について

この項では、文字セットIDを取得する方法について説明します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

この機能はOCIでのみ使用可能です。

  • OCI: lgetchar.c

12.5 LOBへのBFILEデータのロード

この操作では、LOBにBFILEデータをロードします。このプロシージャを使用すると、任意のLOBデータ型である永続LOBインスタンスまたは一時LOBインスタンスにデータをロードできます。

事前条件

BFILEデータをLOBにロードする前に、次の条件を満たしている必要があります。

  • BFILEが存在すること。

  • ターゲットのLOBインスタンスが存在すること。

使用上のノート

この操作については、次の注意事項があります。

文字データのロード時のLOADCLOBFROMFILEの使用

DBMS_LOB.LOADFROMFILEプロシージャを使用してCLOBまたはNCLOBインスタンスにロードする場合は、BFILEからバイナリ・データを使用してLOBをロードすることになり、暗黙的な文字セット変換は実行されません。このため、文字データをロードする際にはDBMS_LOB.LOADCLOBFROMFILEプロシージャを使用することをお薦めします。

BFILEデータのロード量の指定

表12-2に示すファンクションの量パラメータでは、次のいずれかの値を渡す必要があります。

  • ロードするBFILEの実際のサイズ(バイト単位)以下の量。

  • 最大許容LOBサイズ(バイトで表されます)。この値を渡すと、BFILE全体がロードされます。この方法を使用すると、ロード前にBFILEのサイズを確認せずにBFILE全体をロードできます。最大許容LOBサイズを取得するには、表12-2に示す方法を使用します。

表12-2 ファイルからのロード操作用の最大LOBサイズ

環境 機能 最大LOBサイズを渡すために取得する値
DBMS_LOB DBMS_LOB.LOADBLOBFROMFILE DBMS_LOB.LOBMAXSIZE
DBMS_LOB DBMS_LOB.LOADCLOBFROMFILE DBMS_LOB.LOBMAXSIZE
OCI OCILobLoadFromFile2() UB8MAXVAL
OCI OCILobLoadFromFile() (LOBのサイズが4GB未満の場合) UB4MAXVAL

構文

各プログラム環境でこの操作を使用する方法の詳細は、次のマニュアルを参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lloaddat.sql

  • OCI: lloaddat.c

  • Java (JDBC): lloaddat.java

関連項目:

  • LOADBLOBFROMFILEおよびLOADCLOBFROMFILEプロシージャによって、このプロシージャの機能が実装されるため、バイナリ・データおよび文字データのロード機能が向上します。(改善されたプロシージャは、PL/SQL環境のみで使用可能です。)可能なかぎり、機能が向上したプロシージャを使用することをお薦めします。詳細は、BLOBへのBFILEデータのロードについておよびCLOBまたはNCLOBへのBFILEデータのロードを参照してください。

  • この操作のかわりに、SQL*Loaderを使用して永続LOBのデータをファイルシステム内のファイルから直接ロードすることもできます。詳細は、SQL*Loaderを使用したLOBのロードを参照してください。

  • DBMS_LOB.LOADCLOBFROMFILEプロシージャの詳細は、「CLOBまたはNCLOBへのBFILEデータのロード」を参照してください

12.6 BLOBへのBFILEデータのロードについて

このプロシージャでは、BLOBBFILEデータをロードします。このプロシージャを使用すると、任意の永続または一時BLOBインスタンスにデータをロードできます。

関連項目:

事前条件

このプロシージャをコールする前に、次の条件を満たしている必要があります。

  • ターゲットのBLOBインスタンスが存在すること。

  • ソースBFILEが存在すること。

  • BFILEをオープンしていること。(このプロシージャをコールした後、いずれかの時点でBFILEをクローズする必要があります。)

使用上のノート

この操作では、次のことに注意してください。

戻される新規オフセット

DBMS_LOB.LOADBLOBFROMFILEを使用してBLOBにバイナリ・データをロードすると、DBMS_LOB.LOADFROMFILEを使用した場合と同じ結果になりますが、BLOBの新規オフセットも戻されます。

BFILEデータのロード量の指定

DBMS_LOB.LOADBLOBFROMFILEファンクションの量パラメータでは、次のいずれかの値を渡す必要があります。

  • ロードするBFILEの実際のサイズ(バイト単位)以下の量。

  • 許容される最大LOBサイズはDBMS_LOB.LOBMAXSIZEです。この値を渡すと、ファンクションによってBFILE全体がロードされます。この方法は、BFILEのサイズをイントロスペクトせずにBFILE全体をロードする場合に役立ちます。

    関連項目:

    表12-2

構文

このプロシージャの構文の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』「DBMS_LOB」のLOADBLOBFROMFILEプロシージャに関する項を参照してください。

この例はPL/SQLでのみ使用可能です。他のプログラム環境では、このAPIは提供されません。オンライン・ファイルはlldblobf.sqlです。この例は次を示します。

  • LOADBLOBFROMFILEを使用して、最初にBFILEの長さを取得することなくファイル全体をロードする方法。

  • オフセットの戻り値を使用して、実際にロードされたデータ量を計算する方法。

12.7 CLOBまたはNCLOBへのBFILEデータのロード

このプロシージャでは、CLOBまたはNCLOBBFILE文字データをロードします。このプロシージャを使用すると、任意の永続または一時CLOBまたはNCLOBインスタンスにデータをロードできます。

関連項目:

事前条件

このプロシージャをコールする前に、次の条件を満たしている必要があります。

  • ターゲットのCLOBまたはNCLOBインスタンスが存在すること。

  • ソースBFILEが存在すること。

  • BFILEをオープンしていること。(このプロシージャをコールした後、いずれかの時点でBFILEをクローズする必要があります。)

使用上のノート

このプロシージャのコール時に、BFILEの文字セットIDを指定できます。これにより、BFILEデータの文字セットが宛先のCLOBまたはNCLOB文字セットに正しく変換されることが保証されます。

BFILEデータのロード量の指定

DBMS_LOB.LOADCLOBFROMFILEファンクションの量パラメータでは、次のいずれかの値を渡す必要があります。

  • ロードするBFILEデータの実際のサイズ(文字単位)以下の量。

  • 最大許容LOBサイズ: DBMS_LOB.LOBMAXSIZE

    この値を渡すと、ファンクションによりBFILE全体がロードされます。この方法は、BFILEのサイズをイントロスペクトせずにBFILE全体をロードする場合に役立ちます。

構文

このプロシージャの構文の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』「DBMS_LOB」のLOADCLOBFROMFILEプロシージャに関する項を参照してください。

12.7.1 PL/SQL: LOBへのBFILEの文字データのロードについて

次の項目の例を示します。

  • デフォルトCSID(0)の使用方法。

  • BFILEに対してgetlengthをコールせずに、ファイル全体をロードする方法。

  • 戻されたオフセット値を使用して、実際にロードしたデータ量を計算する方法。

この例では、ad_sourceUTF8文字セット・フォーマットのBFILEで、データベースの文字セットがUTF8であることを想定しています。オンライン・ファイルはlldclobf.sqlです。

12.7.2 PL/SQL: 異なるLOBへの文字データ・セグメントのロードについて

次の項目の例を示します。

  • NLS_CHARSET_IDファンクションを使用して、文字セット名から文字セットIDを取得する方法。

  • 戻されたオフセット値および言語コンテキストlang_ctxを使用して、1つのBFILEから複数のLOBにストリームのデータをロードする方法。

  • 警告メッセージの読取り方法。

この例では、ad_file_ext_01JA16TSTSETフォーマットのBFILEで、データベースの各国語文字セットがAL16UTF16であることを想定しています。オンライン・ファイルはlldclobs.sqlです。

12.8 LOBがオープンしているかどうかの確認

この操作では、LOBがオープンしているかどうかを確認します。

事前条件

このプロシージャを実行する前に、LOBインスタンスが存在する必要があります。

使用上のノート

LOBがオープンしている場合は、セッション中のいずれかの時点でクローズする必要があります。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lisopen.sql

  • OCI: lisopen.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lisopen.java

12.8.1 Java(JDBC): LOBがオープンしているかどうかの確認

次に、BLOBまたはCLOBの確認方法を示します。

12.8.1.1 CLOBがオープンしているかどうかの確認

JDBCアプリケーションでCLOBがオープンしているかどうかを確認するには、oracle.sql.CLOBで定義されているisOpenメソッドを使用します。戻されたブール値は、以前にCLOBがオープンされているかどうかを示します。isOpenメソッドは次のように定義します。

/** 
  * Check whether the CLOB is opened. 
  * @return true if the LOB is opened. 
  */ 
public boolean isOpen () throws SQLException

次に例を示します。

CLOB clob = ... 
 // See if the CLOB is opened 
 boolean isOpen = clob.isOpen ();
...
12.8.1.2 BLOBがオープンしているかどうかの確認

JDBCアプリケーションでBLOBがオープンしているかどうかを確認するには、oracle.sql.BLOBで定義されているisOpenメソッドを使用します。戻されたブール値は、以前にBLOBがオープンされているかどうかを示します。isOpenメソッドは次のように定義します。

/** 
 * Check whether the BLOB is opened. 
 * @return true if the LOB is opened. 
 */ 
 public boolean isOpen () throws SQLException

次に例を示します。

BLOB blob = ... 
// See if the BLOB is opened 
boolean isOpen = blob.isOpen ();
...

12.9 LOBデータの表示について

この項では、LOBデータの読取りに使用できるAPIについて説明します。この操作を使用してLOBデータをバッファに読み取ることができます。この操作は、アプリケーションで大量のLOBデータを表示したり、データ・ストリーム操作が必要な場合に役立ちます。

使用上のノート

これらのAPIを使用する場合は、次のことに注意してください。

ストリーム・メカニズム

大量のLOBデータを最も効率よく読み取るには、ストリーム・メカニズムを有効にしたOCILobRead2()を使用します。

量パラメータ

表12-3に示すAPIの場合、量パラメータに渡す値には制限があります。

表12-3 量パラメータの最大LOBサイズ

環境 機能 量パラメータの値の制限

DBMS_LOB

DBMS_LOB.READ

32KBのバッファ・サイズ。

OCI

OCILobRead()

(LOBのサイズが4GB未満の場合)

UB4MAXVAL

この量を指定するとファイル全体が読み取られます。

OCI

OCILobRead2()

(LOBのサイズが任意の場合)

UB8MAXVAL

この量を指定するとファイル全体が読み取られます。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): ldisplay.sql

  • OCI: ldisplay.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): ldisplay.java

12.10 LOBからのデータの読取りについて

この項では、OCILobRead2()を使用してLOBからデータを読み取る方法について説明します。

使用上のノート

この操作を使用する場合は、次のことに注意してください。

OCIでのストリーム読取り

大量のLOBデータを最も効率よく読み取るには、ポーリングまたはコールバックによってストリーム・メカニズムを有効にしたOCILobRead2()を使用します。そのためには、次のようにoffsetパラメータを使用して読取り開始位置を指定します。

ub8  char_amt =  0;
ub8  byte_amt =  0;
ub4  offset = 1000;

OCILobRead2(svchp, errhp, locp, &byte_amt, &char_amt, offset, bufp, bufl,
            OCI_ONE_PIECE, 0, 0, 0, 0);

ポーリング・モードを使用すると、バッファがいっぱいにならない場合があるため、各OCILobRead2()コール後にbyte_amtパラメータの値を調べて、バッファに何バイト読み取られたかを確認してください。

コールバックを使用する場合、lenpパラメータはコールバックへの入力で、バッファ内で格納されたバイト数を示します。バッファの空き領域を確認するため、コールバック処理中にlenpパラメータをチェックしてください。

チャンク・サイズ

チャンクとは1つまたは複数のOracleブロックです。LOBを含む表を作成する場合に、BasicFiles LOB用のチャンク・サイズを指定できます。これは、LOB値に対してアクセスまたは変更を行うときに、Oracle Databaseが使用するデータ・サイズに対応します。チャンクの一部はシステム関連の情報を格納し、残りはLOB値を格納します。使用するAPIには、LOBチャンク内で使用され、LOB値を格納している領域の量を戻すファンクションがあります。PL/SQLでは、DBMS_LOB.GETCHUNKSIZEを使用します。OCIでは、OCILobGetChunkSize()を使用します。SecureFilesでは、CHUNKは、アドバイザ・サイズで、後方互換性のために使用します。

パフォーマンスを改善するには、これらのファンクションの1つによって戻された値を複数回使用してwrite要求を実行します。これは、ディスクからのデータの読取り時に、Oracleデータベースで使用されているサイズと同じ単位を使用するためです。アプリケーションで問題が発生しないかぎり、同じLOBチャンクに複数回のLOB読取りコールを発行するのではなく、チャンク全体の取得に十分なサイズでバッチ読取りを行うと、パフォーマンスが向上します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lread.sql

  • OCI: lread.c

  • Java (JDBC): lread.java

12.11 LOB配列読取りについて

この項では、OCILobArrayRead()を使用して、1回のラウンドトリップで複数のロケータに対してLOBデータを読み取る方法について説明します。

使用上のノート

このファンクションを使用すると、サイズ範囲が512KB未満のLOBを読み取る場合のパフォーマンスが向上します。OCIアプリケーションの例では、プログラムに次のようなSQL文が用意されているものとします。

SELECT lob1 FROM lob_table for UPDATE;

lob1はLOB列であり、lob_arrayはLOB列に対応する定義変数の配列です。

OCILobLocator * lob_array[10];

...
 for (i=0; i<10, i++)        /* initialize array of locators */
    lob_array[i] = OCIDescriptorAlloc(..., OCI_DTYPE_LOB, ...);
 
...
 
OCIDefineByPos(..., 1, (dvoid *) lob_array, ... SQLT_CLOB, ...);
 
/* Execute the statement with iters = 10 to do an array fetch of 10 locators. */
OCIStmtExecute ( <service context>, <statement handle>, <error handle>,
                 10,    /* iters  */ 
                 0,     /* row offset */
                 NULL,  /* snapshot IN */
                 NULL,  /* snapshot out */
                 OCI_DEFAULT /* mode */);
...
 
  ub4 array_iter = 10;
  char  *bufp[10];
  oraub8 bufl[10];
  oraub8 char_amtp[10];
  oraub8 offset[10];  
 
 for (i=0; i<10; i++)
  {
    bufp[i] = (char *)malloc(1000);
    bufl[i] = 1000;
    offset[i] = 1;
    char_amtp[i] = 1000;  /* Single byte fixed width char set. */
  } 
 
/* Read the 1st 1000 characters for all 10 locators in one
 * round trip. Note that offset and amount need not be 
 * same for all the locators. */
 
OCILobArrayRead(<service context>, <error handle>,
                &array_iter, /* array size */
                lob_array,   /* array of locators */
                NULL,        /* array of byte amounts */
                char_amtp,   /* array of char amounts */
                offset,      /* array of offsets */
       (void **)bufp,        /* array of read buffers */
                bufl,        /* array of buffer lengths */
                OCI_ONE_PIECE,  /* piece information */
                NULL,           /* callback context */
                NULL,           /* callback function */
                0,              /* character set ID - default */
                SQLCS_IMPLICIT);/* character set form */
 
 ...
 
for (i=0; i<10; i++)
  {
    /* Fill bufp[i] buffers with data to be written */
    strncpy (bufp[i], "Test Data------", 15);
    bufl[i] = 1000;
    offset[i] = 50;
    char_amtp[i] = 15;  /* Single byte fixed width char set. */
  } 
 
/* Write the 15 characters from offset 50 to all 10 
 * locators in one round trip. Note that offset and
 * amount need not be same for all the locators. */
 */
 
OCILobArrayWrite(<service context>, <error handle>,
                  &array_iter, /* array size */
                  lob_array,   /* array of locators */
                  NULL,        /* array of byte amounts */
                  char_amtp,   /* array of char amounts */
                  offset,      /* array of offsets */
             (void **)bufp,    /* array of read buffers */
                  bufl,        /* array of buffer lengths */
                  OCI_ONE_PIECE,  /* piece information */
                  NULL,           /* callback context */
                  NULL,           /* callback function */
                  0,              /* character set ID - default */
                  SQLCS_IMPLICIT);/* character set form */
...

ストリーミングのサポート

LOB配列APIは、複数ピースでのLOBデータの読取り/書込みに使用できます。これには、ポーリング手法やコールバック・ファンクションを使用します。これにより、ロケータの配列について複数ピースで順に読取り/書込みが実行されます。ポーリングの場合、各ピースの読取り/書込みの後、array_iterパラメータ(OUT)でそのデータ読取り/書込み時のロケータの索引が示されると、APIがアプリケーションに戻ります。コールバックの場合、array_iterをINパラメータとして各ピースの読取り/書込みを実行すると、ファンクションがコールされます。

次の点に注意してください。

  • いくつかのロケータについては1つのピースでデータを読取り/書込みし、その他のロケータについては複数ピースでデータを読取り/書込みすることが可能です。読取り/書込み対象データの全体が収まるだけの十分なバッファ長を持つロケータについては、データは1つのピースで読取り/書込みされます。

  • アプリケーションでは、ロケータごとに異なる量の値およびバッファ長を使用できます。

  • アプリケーションでは、1つ以上のロケータに対して量の値としてゼロを渡し、これらのロケータに対して純粋なストリーミングを指定できます。読取りの場合、LOBデータはこれらのロケータに対して最後まで読み取られます。書込みの場合、これらのロケータに対してOCI_LAST_PIECEが指定されるまでデータが書き込まれます。

ポーリング・モードでのLOB配列読取り

次の例では、バッファ・サイズが1KBの10個のロケータのそれぞれに対して、10KBのデータが読み取られます。完全なデータを読み取るには、ロケータごとに10ピースが必要です。すべてのデータをフェッチするには、OCILobArrayRead()を100 (10*10)回コールする必要があります。まず、OCI_FIRST_PIECEpieceパラメータとしてOCILobArrayRead()をコールします。このコールで、最初のロケータに対して最初の1Kピースが戻されます。次に、アプリケーションでロケータに対するすべてのピースの読取りが終了し、OCI_SUCCESSが戻されるまでOCILobArrayRead()がループでコールされ、ます。この例では、99回ループしてロケータのピースを順次戻しています。

/* Fetch the locators */ 
...
 
     /* array_iter parameter indicates the number of locators in the array read.
      * It is an IN parameter for the 1st call in polling and is ignored as IN
      * parameter for subsequent calls. As OUT parameter it indicates the locator
      * index for which the piece is read.
      */
 
     ub4    array_iter = 10;
     char  *bufp[10];
     oraub8 bufl[10];
     oraub8 char_amtp[10];
     oraub8 offset[10];
     sword  st;  
 
     for (i=0; i<10; i++)
     {
       bufp[i] = (char *)malloc(1000);
       bufl[i] = 1000;
       offset[i] = 1;
       char_amtp[i] = 10000;       /* Single byte fixed width char set. */
     } 
 
     st =  OCILobArrayRead(<service context>, <error handle>,
                         &array_iter, /* array size */
                         lob_array, /* array of locators */
                         NULL,      /* array of byte amounts */
                         char_amtp, /* array of char amounts */
                         offset,    /* array of offsets */
                (void **)bufp,      /* array of read buffers */
                         bufl,      /* array of buffer lengths */
                         OCI_FIRST_PIECE, /* piece information */
                         NULL,           /* callback context */
                         NULL,           /* callback function */
                         0,              /* character set ID - default */
                         SQLCS_IMPLICIT); /* character set form */
 
     /* First piece for the first locator is read here. 
      * bufp[0]          => Buffer pointer into which data is read.
      * char_amtp[0 ]    => Number of characters read in current buffer
      *
      */ 
 
     While ( st == OCI_NEED_DATA)
     {  
          st =  OCILobArrayRead(<service context>, <error handle>,
                          &array_iter, /* array size */
                          lob_array, /* array of locators */
                          NULL,      /* array of byte amounts */
                          char_amtp, /* array of char amounts */
                          offset,    /* array of offsets */
                 (void **)bufp,      /* array of read buffers */
                          bufl,      /* array of buffer lengths */
                          OCI_NEXT_PIECE, /* piece information */
                          NULL,           /* callback context */
                          NULL,           /* callback function */
                          0,              /* character set ID - default */
                          SQLCS_IMPLICIT);
 
       /* array_iter returns the index of the current array element for which 
        * data is read. for example, aray_iter = 1 implies first locator,
        * array_iter = 2 implies second locator and so on.
        *
        * lob_array[ array_iter - 1]=> Lob locator for which data is read. 
        * bufp[array_iter - 1]      => Buffer pointer into which data is read.
        * char_amtp[array_iter - 1] => Number of characters read in current buffer
        */
 
...
        /* Consume the data here */
...
     }

コールバックによるLOB配列読取り

次の例では、バッファ・サイズが1KBの10個のロケータのそれぞれに対して、10KBのデータが読み取られます。各ロケータには、すべてのデータを読み取るために10ピースが必要です。コールバック関数またはファンクションは100(10 × 10)回コールされ、ピースが順次戻されます。

/* Fetch the locators */ 
...
     ub4    array_iter = 10;
     char  *bufp[10];
     oraub8 bufl[10];
     oraub8 char_amtp[10];
     oraub8 offset[10];
     sword  st;  

     for (i=0; i<10; i++)
     {
       bufp[i] = (char *)malloc(1000);
       bufl[i] = 1000;
       offset[i] = 1;
       char_amtp[i] = 10000;       /* Single byte fixed width char set. */
      }

      st =  OCILobArrayRead(<service context>, <error handle>,
                        &array_iter, /* array size */
                        lob_array,   /* array of locators */
                        NULL,        /* array of byte amounts */
                        char_amtp,   /* array of char amounts */
                        offset,      /* array of offsets */
               (void **)bufp,        /* array of read buffers */
                        bufl,        /* array of buffer lengths */
                        OCI_FIRST_PIECE,  /* piece information */
                        ctx,              /* callback context */
                        cbk_read_lob,     /* callback function */
                        0,                /* character set ID - default */
                        SQLCS_IMPLICIT);
...
/* Callback function for LOB array read. */
sb4 cbk_read_lob(dvoid *ctxp, ub4 array_iter, CONST dvoid *bufxp, oraub8 len,
                 ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp)
{  
   static ub4 piece_count = 0;
   piece_count++;  
   switch (piece)
   {
    case OCI_LAST_PIECE: 
      /*--- buffer processing code goes here ---*/ 
(void) printf("callback read the %d th piece(last piece) for %dth locator \n\n",
                piece_count, array_iter ); 
      piece_count = 0; 
      break; 
    case OCI_FIRST_PIECE: 
      /*--- buffer processing code goes here ---*/ 
      (void) printf("callback read the 1st piece for %dth locator\n",
                    array_iter); 
    /* --Optional code to set changed_bufpp and changed_lenp if the buffer needs
         to be changed dynamically --*/ 
      break; 
    case OCI_NEXT_PIECE: 
      /*--- buffer processing code goes here ---*/ 
      (void) printf("callback read the %d th piece for %dth locator\n",
                    piece_count, array_iter); 
      /* --Optional code to set changed_bufpp and changed_lenp if the  buffer
           must be changed dynamically --*/ 
      break; 
      default:
      (void) printf("callback read error: unkown piece = %d.\n", piece); 
      return OCI_ERROR; 
   } 
    return OCI_CONTINUE;
}
...

ポーリングLOB配列読取り

次の例は、変数amtpbuflおよびoffsetを使用したOCILobArrayRead()におけるポーリングLOBデータです。

/* Fetch the locators */ 
...
 
     ub4    array_iter = 10;
     char  *bufp[10];
     oraub8 bufl[10];
     oraub8 char_amtp[10];
     oraub8 offset[10];
     sword  st;  
 
     for (i=0; i<10; i++)
     {
       bufp[i] = (char *)malloc(1000);
       bufl[i] = 1000;
       offset[i] = 1;
       char_amtp[i] = 10000;       /* Single byte fixed width char set. */
     }
 
     /* For 3rd locator read data in 500 bytes piece from offset 101. Amount
      * is 2000, that is, total number of pieces is 2000/500 = 4.
      */
     offset[2] = 101; bufl[2] = 500; char_amtp[2] = 2000;
     
     /* For 6th locator read data in 100 bytes piece from offset 51. Amount
      * is 0 indicating pure polling, that is, data is read till the end of
      * the LOB is reached.
      */
     offset[5] = 51;  bufl[5] = 100; char_amtp[5] = 0;
 
     /* For 8th locator read 100 bytes of data in one piece. Note amount 
      * is less than buffer length indicating single piece read.
      */ 
     offset[7] = 61;  bufl[7] = 200; char_amtp[7] = 100; 
 
     st =  OCILobArrayRead(<service context>, <error handle>,
                         &array_iter, /* array size */
                         lob_array, /* array of locators */
                         NULL,      /* array of byte amounts */
                         char_amtp, /* array of char amounts */
                         offset,    /* array of offsets */
                (void **)bufp,      /* array of read buffers */
                         bufl,      /* array of buffer lengths */
                         OCI_FIRST_PIECE, /* piece information */
                         NULL,           /* callback context */
                         NULL,           /* callback function */
                         0,              /* character set ID - default */
                         SQLCS_IMPLICIT); /* character set form */
 
     /* First piece for the first locator is read here. 
      * bufp[0]          => Buffer pointer into which data is read.
      * char_amtp[0 ]    => Number of characters read in current buffer
      *
      */ 
 
     while ( st == OCI_NEED_DATA)
     {  
          st =  OCILobArrayRead(<service context>, <error handle>,
                          &array_iter, /* array size */
                          lob_array, /* array of locators */
                          NULL,      /* array of byte amounts */
                          char_amtp, /* array of char amounts */
                          offset,    /* array of offsets */
                 (void **)bufp,      /* array of read buffers */
                          bufl,      /* array of buffer lengths */
                          OCI_NEXT_PIECE, /* piece information */
                          NULL,           /* callback context */
                          NULL,           /* callback function */
                          0,              /* character set ID - default */
                          SQLCS_IMPLICIT);
 
       /* array_iter returns the index of the current array element for which 
        * data is read. for example, aray_iter = 1 implies first locator,
        * array_iter = 2 implies second locator and so on.
        *
        * lob_array[ array_iter - 1]=> Lob locator for which data is read. 
        * bufp[array_iter - 1]      => Buffer pointer into which data is read.
        * char_amtp[array_iter - 1]=>Number of characters read in current buffer
        */
 
...
        /* Consume the data here */
...
     }

構文

OCIプログラム環境における構文については、次のマニュアルの項を参照してください。

C (OCI): 『Oracle Call Interfaceプログラマーズ・ガイド』の「LOB関数」のOCILobArrayRead()に関する項。

次のプログラム環境での例を示します。

OCI: lreadarr.c

12.12 LOBの一部の読取り(SUBSTR)

この項では、SUBSTRを使用してLOBの一部を読み取る方法について説明します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lsubstr.sql

  • OCI: 今回のリリースでは例は提供されません。

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lsubstr.java

12.13 2つのLOBの全体または一部の比較

この項では、2つのLOBの全体または一部を比較する方法について説明します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lcompare.sql

  • C(OCI): 今回のリリースでは例は提供されません。

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lcompare.java

12.14 パターン: INSTRを使用したLOB内のパターンの有無の確認

この項では、INSTRを使用してLOB内のパターンの有無を確認する方法について説明します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): linstr.sql

  • C(OCI): 今回のリリースでは例は提供されません。

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): linstr.java

12.15 長さ: LOBの長さの取得

この項では、LOBの長さを取得する方法について説明します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): llength.sql

  • OCI: llength.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): llength.java

12.16 他のLOBへのLOBの全体または一部のコピー

この項では、LOBの全体または一部を他のLOBにコピーする方法について説明します。これらのAPIでは、指定した量のデータがソースLOBから宛先LOBにコピーされます。

使用上のノート

このAPIを使用する場合は、次のことに注意してください。

コピーするデータ量の指定

DBMS_LOB.COPYファンクションのamountパラメータでは、次のいずれかの値を渡す必要があります。

  • ロードするデータの実際のサイズ以下の量。

  • 許容される最大LOBサイズはDBMS_LOB.LOBMAXSIZEです。この値を渡すと、ファンクションでLOB全体がロードされます。この方法は、LOBのサイズをイントロスペクトせずにLOB全体をロードする場合に役立ちます。

文字データの場合は量を文字数で指定し、バイナリ・データの場合はバイト数で指定することに注意してください。

更新前の行のロック

LOB値を更新する予定の場合は、更新前にそのLOBを含む行をロックする必要があります。SQL INSERT文およびUPDATE文は暗黙的に行をロックしますが、SQLプログラムおよびPL/SQLプログラムではSQL SELECT FOR UPDATE文を使用して、またOCIプログラムではOCI pinまたはlock関数を使用して明示的にロックします。

関連項目:

更新後のロケータの状態の詳細は、更新済ロケータを介したLOB更新の例を参照してください

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lcopy.sql

  • OCI: lcopy.c

  • Java (JDBC): lcopy.java

12.17 LOBロケータのコピー

この項では、LOBロケータをコピーする方法について説明します。様々なロケータが、同じデータや異なるデータ、また現在のデータや過去のデータを指すことに注意してください。

関連項目:

PL/SQLで:=演算子を使用して別のLOBを割り当てる方法の詳細は、「読取り一貫性のあるロケータ」を参照してください

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lcopyloc.sql

  • OCI: lcopyloc.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lcopyloc.java

12.18 等値: 2つのLOBロケータが等しいかどうかの確認

この項では、2つのLOBロケータが等しいかどうかを確認する方法について説明します。2つのロケータが等しい場合、それらが同じバージョンのLOBデータを参照していることを意味します。

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL: 今回のリリースでは例は提供されません。

  • OCI: lequal.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lequal.java

12.19 LOBロケータが初期化されているかどうかの確認について

この項では、LOBロケータが初期化されているかどうかを確認する方法について説明します。

関連項目:

表12-1

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL(DBMS_LOBパッケージ): 今回のリリースでは例は提供されません。

  • OCI: linit.c

  • C(OCCI): 今回のリリースでは例は提供されません。

  • Java(JDBC): 今回のリリースでは例は提供されません。

12.20 LOBへの追加について

この項では、バッファの内容をLOBに追加書込みする方法について説明します。

関連項目:

表12-1

使用上のノート

このAPIの使用方法については、次のことに注意してください。

1つずつまたはピース単位の書込み

writeappend操作では、バッファがLOBの終わりに書き込まれます。

OCIでは、このコールを使用してバッファからピース単位でLOBに書き込むことができます。また、コールバックまたは標準のポーリング方法を使用してもピース単位に処理できます。

ピース単位の書込み:コールバックまたはポーリングの使用時期

ピース・パラメータの値がOCI_FIRST_PIECEの場合、データはコールバックまたはポーリングを介して提供される必要があります。

  • コールバック関数またはファンクションがcbfpパラメータ内に定義されている場合、ピースがパイプに書き込まれてから、このコールバック関数またはファンクションをコールして次のピースを取得します。各ピースがbufpから書き込まれます。

  • コールバック関数が定義されていない場合、OCILobWriteAppend2()は、OCI_NEED_DATAエラー・コードを戻します。アプリケーションはOCILobWriteAppend2()を再びコールし、さらにLOBのピースを書き込む必要があります。このモードでは、ピースが別々のサイズで複数の場所に読み取られる場合、コールごとにバッファ・ポインタと長さを変えることができます。pieceパラメータの値がOCI_LAST_PIECEのときは、ピース単位の書込みは終了します。

更新前の行のロック

PL/SQL DBMS_LOBパッケージまたはOCIを使用してLOBの値を更新する前に、LOBを含む行をロックする必要があります。SQL INSERT文およびUPDATE文は暗黙的に行をロックしますが、SQLプログラムおよびPL/SQLプログラムではSQL SELECT FOR UPDATE文を使用して、またOCIプログラムではOCI pinまたはlock関数を使用して明示的にロックします。

関連項目:

更新後のロケータの状態の詳細は、更新済ロケータを介したLOB更新の例を参照してください

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lwriteap.sql

  • OCI: lwriteap.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lwriteap.java

12.21 LOBへのデータの書込みについて

この項では、バッファの内容をLOBに書き込む方法について説明します。

使用上のノート

このAPIの使用方法については、次のことに注意してください。

ストリーム書込み

大量のLOBデータを最も効率よく書き込むには、ポーリングまたはコールバックによってストリーム・メカニズムを有効にしたOCILobWrite2()を使用します。LOBに書き込むデータの量がわかっている場合は、OCILobWrite2()のコール時にそのデータ量を指定します。これにより、ディスク上のLOBデータが確実に連続したものになります。領域を効率的に利用できるのみでなく、LOBデータの連続性により、その後の操作で読み書きの速度が速くなります。

チャンク・サイズ

チャンクとは1つまたは複数のOracleブロックです。LOBを含む表を作成する場合に、LOB用のチャンク・サイズを指定できます。これは、LOB値に対してアクセスまたは変更を行うときに、Oracle Databaseが使用するデータ・サイズに対応します。チャンクの一部はシステム関連の情報を格納し、残りはLOB値を格納します。使用するAPIには、LOBチャンク内で使用され、LOB値を格納している領域の量を戻すファンクションがあります。PL/SQLでは、DBMS_LOB.GETCHUNKSIZEを使用します。OCIでは、OCILobGetChunkSize()を使用します。

書込みパフォーマンスを改善するための戻り値の複数倍の指定

これらのファンクションの1つによって戻された値を複数回使用してwrite要求を実行すると、パフォーマンスが向上します。これは、LOBチャンクがwrite要求ごとにバージョン化されるためです。すべてのwriteを1つのチャンクで行うと、余分なバージョン化は行われません。使用しているアプリケーションに問題がなければ、同じサイズのLOBチャンクで複数回のLOB書込みコールを発行するのではなく、十分なサイズのチャンクにバッチ書込みを行うと、パフォーマンスが向上します。

更新前の行のロック

PL/SQL DBMS_LOBパッケージまたはOCIを使用してLOBの値を更新する前に、LOBを含む行をロックする必要があります。SQL INSERT文およびUPDATE文は暗黙的に行をロックしますが、SQLプログラムおよびPL/SQLプログラムではSQL SELECT FOR UPDATE文を使用して、またOCIプログラムではOCI pinまたはlock関数を使用して明示的にロックします。

関連項目:

更新後のロケータの状態の詳細は、更新済ロケータを介したLOB更新の例を参照してください

DBMS_LOB.WRITEを使用したBLOBへのデータの書込み

16進文字列をDBMS_LOB.WRITE()に渡してBLOBにデータを書き込む場合は、次のガイドラインに従ってください。

  • amountパラメータは、バッファのlengthパラメータ以下にする必要があります。

  • バッファのlengthは((amount*2) - 1)です。このようなガイドラインがあるのは、文字列の2文字が1つの16進文字とみなされ(そして、暗黙的に16進からRAWへの変換が実行され)、文字列の2バイトごとに1 RAWバイトに変換されるためです。

正しい例は、次のとおりです。

declare
   blob_loc  BLOB;
   rawbuf RAW(10);
   an_offset INTEGER := 1;
   an_amount BINARY_INTEGER := 10;
BEGIN
   select blob_col into blob_loc from a_table
where id = 1;
   rawbuf := '1234567890123456789';
   dbms_lob.write(blob_loc, an_amount, an_offset,
rawbuf);
   commit;
END;

前の例のan_amountの値を次の値に置き換えると、エラー・メッセージORA-21560が戻されます。

    an_amount BINARY_INTEGER := 11;

または

    an_amount BINARY_INTEGER := 19;

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lwrite.sql

  • OCI: lwrite.c

  • Java (JDBC): lwrite.java

12.22 LOB配列書込み

この項では、OCILobArrayWrite()を使用して、1回のラウンドトリップで複数のロケータに対してLOBデータを読み取る方法について説明します。

使用上のノート

関連項目:

配列読取り/書込みの例については、LOB配列読取りについてを参照してください。

ポーリング・モードでのLOB配列書込み

次の例では、バッファ・サイズが1KBの10個のロケータのそれぞれに対して、10KBのデータが書き込まれます。OCILobArrayWrite()は、すべてのデータを書き込むために100(10 × 10)回コールされる必要があります。このファンクションは、OCILobWrite2()と同様の方法で使用されます。

/* Fetch the locators */
...
 
/* array_iter parameter indicates the number of locators in the array read.
 * It is an IN parameter for the 1st call in polling and is ignored as IN
 * parameter for subsequent calls. As an OUT parameter it indicates the locator
 * index for which the piece is written.
 */
 
ub4    array_iter = 10;
char  *bufp[10];
oraub8 bufl[10];
oraub8 char_amtp[10];
oraub8 offset[10];
sword  st;
int    i, j; 
 
for (i=0; i<10; i++)
{
  bufp[i] = (char *)malloc(1000);
  bufl[i] = 1000;
  /* Fill bufp here. */
...
  offset[i] = 1;
  char_amtp[i] = 10000;       /* Single byte fixed width char set. */  
}
 
for (i  = 1; i <= 10; i++)
{
 /* Fill up bufp[i-1] here.  The first piece for ith locator would be written from
    bufp[i-1] */
...
    st =  OCILobArrayWrite(<service context>, <error handle>,
                      &array_iter, /* array size */
                      lob_array,   /* array of locators */
                      NULL,        /* array of byte amounts */
                      char_amtp,   /* array of char amounts */
                      offset,      /* array of offsets */
             (void **)bufp,        /* array of write buffers */
                      bufl,        /* array of buffer lengths */
                      OCI_FIRST_PIECE, /* piece information */
                      NULL,            /* callback context */
                      NULL,            /* callback function */
                      0,               /* character set ID - default */
                      SQLCS_IMPLICIT); /* character set form */
 
 for ( j = 2; j < 10; j++) 
 {
 /* Fill up bufp[i-1] here.  The jth piece for ith locator would be written from
    bufp[i-1] */
...
 st =  OCILobArrayWrite(<service context>, <error handle>,
                        &array_iter, /* array size */
                        lob_array,   /* array of locators */
                        NULL,        /* array of byte amounts */
                        char_amtp,   /* array of char amounts */
                        offset,      /* array of offsets */
               (void **)bufp,        /* array of write buffers */
                        bufl,        /* array of buffer lengths */
                        OCI_NEXT_PIECE, /* piece information */
                        NULL,           /* callback context */
                        NULL,           /* callback function */
                        0,              /* character set ID - default */
                        SQLCS_IMPLICIT);
 
    /* array_iter returns the index of the current array element for which
     * data is being written. for example, aray_iter = 1 implies first locator,
     * array_iter = 2 implies second locator and so on. Here i = array_iter.
     *
     * lob_array[ array_iter - 1] => Lob locator for which data is written.
     * bufp[array_iter - 1]       => Buffer pointer from which data is written.
     * char_amtp[ array_iter - 1] => Number of characters written in
     * the piece just written
     */
}

/* Fill up bufp[i-1] here.  The last piece for ith locator would be written from
   bufp[i -1] */
...       
 st =  OCILobArrayWrite(<service context>, <error handle>,
                        &array_iter, /* array size */
                        lob_array,   /* array of locators */
                        NULL,        /* array of byte amounts */
                        char_amtp,   /* array of char amounts */
                        offset,      /* array of offsets */
               (void **)bufp,        /* array of write buffers */
                        bufl,        /* array of buffer lengths */
                        OCI_LAST_PIECE,  /* piece information */
                        NULL,            /* callback context */
                        NULL,            /* callback function */
                        0,               /* character set ID - default */
                        SQLCS_IMPLICIT);
}

...

コールバックによるLOB配列書込み

次の例では、バッファ・サイズが1KBの10個のロケータのそれぞれに対して、10KBのデータが書き込まれます。合計100ピース(ロケータごとに10ピース)を書き込む必要があります。最初のピースはOCILobArrayWrite()コールによって提供されます。コールバック関数またはファンクションは99回コールされ、書込み対象の以降のピースに対してデータが取得されます。

/* Fetch the locators */
...

    ub4    array_iter = 10;
    char  *bufp[10];
    oraub8 bufl[10];
    oraub8 char_amtp[10];
    oraub8 offset[10];
    sword  st; 
 
    for (i=0; i<10; i++)
    {
      bufp[i] = (char *)malloc(1000);
      bufl[i] = 1000;
      offset[i] = 1;
      char_amtp[i] = 10000;       /* Single byte fixed width char set. */
    }
 
 st =  OCILobArrayWrite(<service context>, <error handle>,
                        &array_iter, /* array size */
                        lob_array,   /* array of locators */
                        NULL,        /* array of byte amounts */
                        char_amtp,   /* array of char amounts */
                        offset,      /* array of offsets */
               (void **)bufp,        /* array of write buffers */
                        bufl,        /* array of buffer lengths */
                        OCI_FIRST_PIECE,  /* piece information */
                        ctx,              /* callback context */
                        cbk_write_lob     /* callback function */
                        0,                /* character set ID - default */
                        SQLCS_IMPLICIT);

...

/* Callback function for LOB array write. */
sb4 cbk_write_lob(dvoid *ctxp, ub4 array_iter, dvoid *bufxp, oraub8 *lenp,
                  ub1 *piecep, ub1 *changed_bufpp, oraub8 *changed_lenp)
{
 static ub4 piece_count = 0;
 piece_count++; 

 printf (" %dth piece written  for %dth locator \n\n", piece_count, array_iter);

 /*-- code to fill bufxp with data goes here. *lenp should reflect the  size and
  *   should be less than or equal to MAXBUFLEN -- */
 /* --Optional code to set changed_bufpp and changed_lenp if the buffer must
  *   be changed dynamically --*/

  if (this is the last data buffer for current locator)
     *piecep = OCI_LAST_PIECE;     
  else if (this is the first data buffer for the next locator)
     *piecep = OCI_FIRST_PIECE;
     piece_count = 0;
  else
     *piecep = OCI_NEXT_PIECE;
 
     return OCI_CONTINUE;
    }
...

配列書込みにおけるポーリングLOBデータ

次の例は、変数amtpbuflおよびoffsetを使用したOCILobArrayWrite()におけるポーリングLOBデータです。

/* Fetch the locators */
...
 
ub4    array_iter = 10;
char  *bufp[10];
oraub8 bufl[10];
oraub8 char_amtp[10];
oraub8 offset[10];
sword  st;
int    i, j;
int piece_count; 
 
for (i=0; i<10; i++)
{
  bufp[i] = (char *)malloc(1000);
  bufl[i] = 1000;
  /* Fill bufp here. */
...
  offset[i] = 1;
  char_amtp[i] = 10000;       /* Single byte fixed width char set. */  
}
 
     /* For 3rd locator write data in 500 bytes piece from offset 101. Amount
      * is 2000, that is, total number of pieces is 2000/500 = 4.
      */
     offset[2] = 101; bufl[2] = 500; char_amtp[2] = 2000;
     
     /* For 6th locator write data in 100 bytes piece from offset 51. Amount
      * is 0 indicating pure polling, that is, data is written 
      * till OCI_LAST_PIECE
      */
     offset[5] = 51;  bufl[5] = 100; char_amtp[5] = 0;
 
     /* For 8th locator write 100 bytes of data in one piece. Note amount 
      * is less than buffer length indicating single piece write.
      */ 
     offset[7] = 61;  bufl[7] = 200; char_amtp[7] = 100;
 
for (i  = 1; i <= 10; i++)
{
 /* Fill up bufp[i-1] here.  The first piece for ith locator would be written from
    bufp[i-1] */
...
    /* Calculate number of pieces that must be written */
    piece_count = char_amtp[i-1]/bufl[i-1];
 
    /* Single piece case */
    if (char_amtp[i-1] <= bufl[i-1])
      piece_count = 1;
 
    /* Zero amount indicates pure polling. So we can write as many
     * pieces as needed. Let us write 50 pieces.
     */
    if (char_amtp[i-1] == 0)
      piece_count = 50;
 
    st =  OCILobArrayWrite(<service context>, <error handle>,
                      &array_iter, /* array size */
                      lob_array,   /* array of locators */
                      NULL,        /* array of byte amounts */
                      char_amtp,   /* array of char amounts */
                      offset,      /* array of offsets */
             (void **)bufp,        /* array of write buffers */
                      bufl,        /* array of buffer lengths */
                      OCI_FIRST_PIECE, /* piece information */
                      NULL,            /* callback context */
                      NULL,            /* callback function */
                      0,               /* character set ID - default */
                      SQLCS_IMPLICIT); /* character set form */
 
 for ( j = 2; j < piece_count; j++) 
 {
   /* Fill up bufp[i-1] here. The jth piece for ith locator would be written
    * from bufp[i-1] */
...
   st =  OCILobArrayWrite(<service context>, <error handle>,
                          &array_iter, /* array size */
                          lob_array,   /* array of locators */
                          NULL,        /* array of byte amounts */
                          char_amtp,   /* array of char amounts */
                          offset,      /* array of offsets */
                 (void **)bufp,        /* array of write buffers */
                          bufl,        /* array of buffer lengths */
                          OCI_NEXT_PIECE, /* piece information */
                          NULL,           /* callback context */
                          NULL,           /* callback function */
                          0,              /* character set ID - default */
                          SQLCS_IMPLICIT);
 
    /* array_iter returns the index of the current array element for which
     * data is being written. for example, aray_iter = 1 implies first locator,
     * array_iter = 2 implies second locator and so on. Here i = array_iter.
     *
     * lob_array[ array_iter - 1] => Lob locator for which data is written.
     * bufp[array_iter - 1]       => Buffer pointer from which data is written.
     * char_amtp[ array_iter - 1] => Number of characters written in
     * the piece just written
     */
}
 
/* Fill up bufp[i-1] here.  The last piece for ith locator would be written from
 * bufp[i -1] */
...
 
/* If piece_count is 1 it is a single piece write. */
if (piece_count[i] != 1)
  st =  OCILobArrayWrite(<service context>, <error handle>,
                          &array_iter, /* array size */
                          lob_array,   /* array of locators */
                          NULL,        /* array of byte amounts */
                          char_amtp,   /* array of char amounts */
                          offset,      /* array of offsets */
                 (void **)bufp,        /* array of write buffers */
                          bufl,        /* array of buffer lengths */
                          OCI_LAST_PIECE,  /* piece information */
                          NULL,            /* callback context */
                          NULL,            /* callback function */
                          0,               /* character set ID - default */
                          SQLCS_IMPLICIT);
}
 
...

構文

OCIプログラム環境における構文については、次のマニュアルの項を参照してください。

C (OCI): 『Oracle Call Interfaceプログラマーズ・ガイド』の「LOB関数」のOCILobArrayWrite()に関する項。

次のプログラム環境での例を示します。

OCI: lwritearr.c

12.23 LOBデータの切捨てについて

この項では、LOBを指定のサイズまで切り捨てる方法について説明します。

関連項目:

表12-1

使用上のノート

このAPIの使用方法については、次のことに注意してください。

更新前の行のロック

PL/SQL DBMS_LOBパッケージまたはOCIを使用してLOBの値を更新する前に、LOBを含む行をロックする必要があります。SQL INSERT文およびUPDATE文は暗黙的に行をロックしますが、次の方法を使用すると明示的にロックを行うことができます。

  • SQLプログラムおよびPL/SQLプログラムではSELECT FOR UPDATE文。

  • OCIプログラムではOCI pinまたはlock関数。

関連項目:

更新後のロケータの状態の詳細は、更新済ロケータを介したLOB更新の例を参照してください

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): ltrim.sql

  • OCI: ltrim.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): ltrim.java

12.24 LOBの一部の消去について

この項では、LOBの一部を消去する方法について説明します。

関連項目:

表12-1

使用上のノート

このAPIの使用方法については、次のことに注意してください。

更新前の行のロック

PL/SQL DBMS_LOBパッケージまたはOCIを使用してLOBの値を更新する前に、LOBを含む行をロックする必要があります。INSERT文およびUPDATE文は暗黙的に行をロックしますが、SQLプログラムおよびPL/SQLプログラムではSELECT FOR UPDATE文を使用して、またOCIプログラムではOCI pinまたはlock関数を使用して明示的にロックします。

関連項目:

更新後のロケータの状態の詳細は、「更新済ロケータを介したLOB更新の例」を参照してください

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): lerase.sql

  • OCI: lerase.c

  • C++(OCCI): 今回のリリースでは例は提供されません。

  • Java (JDBC): lerase.java

12.25 LOBインスタンスが一時LOBであるかどうかの確認

この項では、LOBインスタンスが一時LOBであるかどうかを確認する方法について説明します。

関連項目:

表12-1

構文

各プログラム環境における構文については、次のマニュアルの項を参照してください。

次のプログラム環境での例を示します。

  • PL/SQL (DBMS_LOBパッケージ): listemp.sql

  • OCI: listemp.c

12.25.1 Java(JDBC): BLOBが一時LOBであるかどうかの確認

BLOBが一時LOBかどうかの判別に、JDBCアプリケーションでは、現在のBLOBオブジェクトについてはisTemporaryインスタンス・メソッドを使用し、指定されたBLOBオブジェクトについては、そのBLOBオブジェクトを静的なisTemporaryメソッドに渡して確認できます。これらの2つのメソッドは、listempb.javaで定義されています。

このJDBC APIによって、DBMS_LOB.isTemporary()を使用する以前の回避策が必要なくなります。

CLOBが一時的かどうかを判定するには、JDBCアプリケーションでisTemporaryインスタンス・メソッドを使用して現在のCLOBオブジェクトが一時的かどうかを判定する方法と、CLOBオブジェクトを静的なisTemporaryメソッドに渡す方法があります。これらの2つのメソッドは、listempc.javaで定義されています。

12.26 BLOBからCLOBへの変換

PL/SQL DBMS_LOB.CONVERTTOCLOBプロシージャを使用すると、BLOBインスタンスをCLOBに変換できます。

この方法は、CLOBに格納する文字データがバイナリ形式で格納されている場合に役立ちます。このプロシージャのコール時に、バイナリ・データの文字セットを指定します。

関連項目:

このプロシージャの構文と使用方法の詳細は、Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンスを参照してください

12.27 CLOBからBLOBへの変換

PL/SQL DBMS_LOB.CONVERTTOBLOBプロシージャを使用すると、CLOBインスタンスをBLOBインスタンスに変換できます。この方法では、LOB APIを使用して文字データをバイナリ・データに簡単に変換できます。参照

関連項目:

このプロシージャの構文と使用方法の詳細は、Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンスを参照してください

12.28 読取り一貫性の保証

このスクリプトを使用して、NOLOGGINGまたはFILESYSTEM_LIKE_LOGGING LOBを持つ、読取り非一貫性のないリカバリ・ポイントを把握している表のホット・バックアップを確実に取ることができます。

ALTER DATABASE FORCE LOGGING;
SELECT CHECKPOINT_CHANGE# FROM V$DATABASE;  --Start SCN

SCN(システム変更番号)は、トランザクションがコミットされた時点のデータベースのバージョンを定義するスタンプです。

バックアップを実行します。

次のスクリプトを実行します。

ALTER SYSTEM CHECKPOINT GLOBAL;
SELECT CHECKPOINT_CHANGE# FROM V$DATABASE;  --End SCN
ALTER DATABASE NO FORCE LOGGING;

データベースで生成されたアーカイブ・ログをバックアップします。少なくとも、開始SCNと終了SCN(両方のSCN時点を含む)の間のアーカイブ・ログはバックアップする必要があります。

読取り非一貫性のない時点までリストアするため、不完全なリカバリの時点として終了SCNまでリストアします。終了SCNより後のSCNにリカバリを実行すると、NOLOGGING LOBで読取り非一貫性が発生する可能性があります。

SecureFilesでは、メディア・リカバリ中に読取り非一貫性が検出されると、データベースにより一貫性のないブロックがホールとして処理され、BLOB0が、CLOBに充填文字が格納されます。