3.1 始める前に

一時LOBでの作業を開始する前に、この項のトピックを必ず確認してください。

3.1.1 一時LOBの作成

この項では、クライアント・プログラムで一時LOBを作成または生成する方法について説明します。

一時LOBインスタンスは、次のいずれかの方法で作成できます。

  • 指定されたLOBデータ型の変数を宣言し、一時LOB作成APIに渡します。たとえば、PL/SQLではDBMS_LOB.CREATETEMPORARY、OCIではOCILobCreateTemporary()です。
  • 一時LOBを生成するSQLまたはPL/SQL組込みファンクション(SUBSTR関数など)を起動します。
  • 一時LOBをOUTバインド変数または戻り値として戻すPL/SQLストアド・プロシージャまたはファンクションを起動します。

一時LOBインスタンスは、スコープ外になるか、セッションが終了するか、またはインスタンスを明示的に解放するまで、アプリケーションに存在します。

一時LOBは、サイズに応じてPGAメモリーまたは一時表領域のいずれかに存在します。PGAメモリーおよび一時表領域に、アプリケーションで使用される一時LOBに十分な大きさの領域があることを確認してください。

ノート:

  • 一時LOBインスタンスを解放してシステム・リソースを解放することをお薦めします。そうしないと、一時LOBが蓄積され、システムがかなり遅くなる可能性があります。
  • Oracle Databaseリリース21c以降では、一時LOBを解放する前に、LOBが一時LOBであるか永続LOBであるかを確認する必要はありません。LOBに対してDBMS_LOB.FREETEMPORARYプロシージャまたはOCILobFreeTemporary()関数を呼び出すと、次のいずれかの操作が実行されます。
    • 一時LOBの場合は、LOBを解放します。
    • 永続LOBの場合、何も行われません(no-op)。

3.1.2 クライアント側での一時LOBの処理

クライアント・プログラムによって生成される一時LOBを処理する際には、この項で説明する側面を考慮する必要があります。

一時LOBの蓄積の防止

JDBCやOCIなどのクライアント・プログラムがSQLまたはPL/SQLからLOBロケータを取得し、一時LOBを生成している疑いがある場合は、アプリケーションがLOBを使用したらすぐにLOBを解放します。一時LOBを解放しないと、一時LOBが蓄積され、システムがかなり遅くなる可能性があります。

ノート:

一時LOB期間は、クライアント側に送信されると常にSESSIONにアップグレードされます。

たとえば、一時LOBの蓄積を防ぐために、OCIアプリケーションでは次のシナリオでOCILobFreeTemporary()関数を呼び出す必要があります。

  • SELECT文中に定義からロケータを取得した後、またはPL/SQLプロシージャまたはファンクションからOUTバインド変数を取得した後。必要な操作の実行が終了したら、すぐに一時LOBを解放することをお薦めします。そうでない場合は、変数を再利用して次の行をフェッチする前、または別の目的で解放する必要があります。
  • ポインタ割当て(<var1 = var2>など)を実行する前に、変数<var1>の古い一時LOBを解放します。
LOB割当て

OCIプログラムでOCILobLocatorポインタを割り当てる場合は、代入(=)演算子を使用する際に特に注意が必要です。ポインタ割当てにより、LOBの簡単なコピーが作成されます。ポインタの割当て後は、ソースLOBとターゲットLOBが同じデータ・コピーを指します。つまり、いずれかの変数でOCILobFreeTemporary()関数を呼び出すと、両方の変数が存在しないLOBを指します。

これらのセマンティクスは、割当てを実行するOCILobLocatorAssign()関数などのLOB APIの使用とは異なります。これらのAPIを使用すると、ロケータは割当て後にデータの独立したコピーを論理的に指します。つまり、最終的には、各LOB記述子でOCILobFreeTemporary()関数を個別に呼び出し、操作に関連するすべてのLOBを解放する必要があります。

一時LOBの場合、ポインタ割当てを実行する前に、OCIFreeTemporary()関数を呼び出し、ターゲットLOBロケータ内の一時LOBを解放する必要があります。これに対して、OCILobLocatorAssign()関数を使用すると、割当てが発生する前に、ターゲットLOBロケータ変数内の元の一時LOB (存在する場合)が自動的に解放されます。