9.1 始める前に

プログラム・インタフェースを使用してLOBで作業する前に、LOBロケータを使用して知っておく必要がある概念について学習します。

9.1.1 LOBロケータの取得

すべてのLOB APIでは、有効なLOBロケータを入力として渡す必要があります。この項では、LOBロケータを使用してLOB変数を移入する様々な方法について説明します。

すべてのLOB APIでは、有効なLOBロケータを入力として渡す必要があります。次のいずれかの方法を使用して、アプリケーションのLOB変数にLOBロケータを移入します。
  • 永続LOB:最初にLOB列を含む表を作成してから、LOB列に値を挿入し、LOBロケータを選択します。LOBロケータを使用して既存のLOBを変更するには、トランザクション中に他のデータベース・ユーザーがLOBに書き込むのを防ぐために、表内の行をロックする必要があります。

    関連項目:

  • 一時LOB: 一時LOBを作成するには、DBMS_LOB.CREATETEMPORARYなどのAPIを使用するか、一時LOBを戻すSQLファンクションまたはPL/SQLファンクションを起動します。

    関連項目:

    一時LOB

9.1.2 LOBのオープン操作とクローズ操作

LOB APIには、LOBインスタンスを明示的にオープンおよびクローズできる操作が組み込まれています。

永続LOBインスタンスまたは一時LOBインスタンスは、BLOBCLOBまたはNCLOBのいずれの型でもオープンおよびクローズできます。LOBをオープンすると、次の一方または両方の結果となります。
  • LOBを読取り専用モードでオープンした場合

    この場合、LOB(LOBロケータとLOB値の両方)は、明示的にクローズするまではセッションで変更できません。たとえば、このモードでオープンすることで、重要な操作でLOBを使用しているときに、そのLOBがプログラムの他の部分により変更されないようにできます。操作の実行後に、LOBをクローズできます。

  • LOBの読取り/書込みモードでのオープン

    LOBを読取り/書込みモードでオープンすると、そのLOBをクローズするまでLOB列の索引メンテナンスが遅延されます。LOBを読取り/書込みモードでオープンできるのは、そのLOB列にファンクション索引またはドメイン索引があり、そのLOBに書き込むたびにデータベースで索引メンテナンスが実行されないようにする場合のみです。オープンしているLOBに対して複数の書込み操作を実行する場合は、この方法でオープンするとアプリケーションのパフォーマンスを改善できます。LOB列のすべての索引は、そのLOBを明示的にクローズするまで無効であることに注意してください。

    LOBインスタンスを明示的にオープンしない場合、LOBに対する変更が行われるたびにLOBインスタンスが暗黙的にオープンおよびクローズされます。LOBの暗黙的クローズごとに、LOB列のファンクション索引およびドメイン索引の索引メンテナンスが実行されます。これは、LOBインスタンスが変更されるとすぐにLOBの索引が更新されることを意味します。これらの索引は常に有効であり、いつでも使用できます。

LOBのオープン状態は、LOBロケータではなくLOBインスタンスに関連付けられています。ロケータには、それが指すLOBインスタンスがオープンしているかどうかを示す情報は格納されません。

明示的にオープンしたLOBインスタンスは、次の場所でクローズする必要があります。
  • トランザクションを起動するDML文の間(SELECT ... FOR UPDATEおよびCOMMITを含む)
  • 自律型トランザクション・ブロック内
  • セッションの終了前(セッションで進行中のトランザクションがない場合)。

LOBインスタンスを明示的にクローズしない場合、セッションの終了時に暗黙的にクローズされ、索引トリガーは起動されません。つまり、LOB列の索引は更新されません。この場合は、LOB列に対する索引を再作成する必要があります。

オープン状態にあるLOBインスタンスに対するトランザクションをコミットすると、エラーが発生します。このエラーが発生すると、LOBインスタンスが暗黙的にクローズされてLOBインスタンスに対する変更が保存され、トランザクションがコミットされますが、LOB列の索引は更新されません。この場合は、LOB列に対する索引を再作成する必要があります。

その後トランザクションをロールバックすると、LOBインスタンスは前の状態にロールバックされますが、LOBインスタンスは明示的にオープンされません。

明示的にオープンしたLOBがオープン状態かクローズ状態かを追跡してください。次の場合にはエラーが発生します。
  • すでに明示的にオープンしているLOBインスタンスを明示的にオープンする場合。
  • すでに明示的にクローズしているLOBインスタンスを明示的にクローズする場合。

このエラーは、LOBインスタンスへのアクセスに同じロケータを使用しているかどうかに関係なく発生します。

9.1.3 チャンク境界での読取りおよび書込み

パフォーマンスを向上させるには、GETCHUNKSIZEファンクションによって戻される値の倍数であるオフセットおよび量を使用してLOBの読取りおよび書込みを実行する必要があります。

アプリケーションに問題がなければ、同じLOBチャンクで複数回の読取りまたは書込みコールを発行するのではなく、チャンク全体に十分なサイズのバッチ読取りおよび書込みを行う必要があります。

9.1.4 LOBデータおよびLOB長のプリフェッチ

JDBC、OCI、ODP.NETなどのほとんどのクライアントでは、フェッチ中にLOBロケータとともにデータおよびメタデータ(長さおよびチャンク・サイズ)の一部をプリフェッチすることで、サーバー・ラウンドトリップ数を削減できます。これは、永続LOB、一時LOBおよびBFILEに適用されます。

サイズが小さいLOBから中程度のLOBの場合、ほとんどのLOBがプリフェッチ・サイズより小さくなるようにプリフェッチ長を設定することをお薦めします。

LOBプリフェッチ・サイズはセッション・レベルで設定でき、文レベルまたは列レベルで上書きできます。

9.1.5 文字セットIDの取得

DBMS_LOB.LOADCLOBFROMFILEOCILobRead2()およびOCILobWrite2()などの一部のLOB APIは、入力として文字セットIDを受け取ります。文字セットIDを確認するには、文字セット名を知っている必要があります。

データベース文字セットおよび各国語文字セットとして有効な文字セット名がリストされているV$NLS_VALID_VALUESビューから選択できます。次に、目的の文字セット名を1つの文字列引数に指定したNLS_CHARSET_IDファンクションをコールします。文字セットIDが整数で戻されます。

UTF16はデータベースまたは各国語文字セットとしては使用できませんが、LOB APIではデータベース変換のためにサポートされています。UTF16には文字set ID = 1000を使用し、OCIではOCI_UTF16IDを使用できます。

関連項目:

9.1.6 LOB API

LOB変数が永続LOBロケータまたは一時LOBロケータで初期化されると、LOBに対する後続の読取り操作は、DBMS_LOBパッケージのサブプログラムなどのAPIを使用して実行できます。

LOBでサポートされる操作は、次のカテゴリに分類されます。

表9-1 LOB APIでサポートされている操作

分類 操作 DBMS_LOBまたはOCILobでの関数/プロシージャの例
健全性チェック LOB変数が初期化されているかどうかの確認 OCILobLocatorIsInit
BLOBまたはCLOBロケータがSecureFileかどうかを確認 ISSECUREFILE
オープンとクローズ LOBをオープン OPEN
LOBがオープンしているかどうかの確認 ISOPEN
LOBのクローズ CLOSE
読取り操作 LOB長の取得 GETLENGTH
データベース構成のLOB記憶域制限を取得します GET_STORAGE_LIMIT
最適な読取りまたは書込みサイズを取得します GETCHUNKSIZE
指定されたオフセットからLOBのデータを読み取ります READ
SUBSTRを使用して、指定されたオフセット以降のLOB値の一部を返す SUBSTR
INSTRを使用して、LOB内のパターンの一致位置を返す INSTR
変更操作 指定されたオフセットからLOBにデータを書き込みます WRITE
データをLOBの終わりに書き込みます。 WRITEAPPEND
指定のオフセットから開始して、LOBの一部を消去します ERASE
LOB値の指定された長さまでの切捨て TRIM
複数のロケータを含む操作 2つのLOBロケータが同じかどうかの確認 OCILobIsEqual
2つのLOBの値の全体または一部の比較 COMPARE
LOB値を別のLOBに追加します APPEND
LOBの全体または一部を他のLOBにコピーします。 COPY
LOBロケータsrcのLOBロケータdstへの割当て dst:=src, OCILobLocatorAssign
BLOBCLOBに、またはCLOBBLOBに変換 CONVERTTOBLOB、CONVERTTOCLOB
BFILEデータのLOBへのロード LOADCLOBFROMFILE、LOADBLOBFROMFILE
SecureFilesに固有の操作 SecureFilesのオプション(重複除外、圧縮、暗号化)を戻します。 GETOPTIONS
SecureFilesのLOB機能(重複除外および圧縮)を設定します SETOPTIONS
SecureFilesのコンテンツ文字列を取得します。 GETCONTENTTYPE
SecureFilesのコンテンツ文字列を設定します。 SETCONTENTTYPE
LOBの指定されたオフセットから指定された長さのデータを削除します。 FRAGMENT_DELETE
LOBの指定されたオフセットに、指定されたデータ(32KB未満)を挿入します。 FRAGMENT_INSERT
指定されたオフセットから他の指定されたオフセットに、指定されたバイト数を移動します。 FRAGMENT_MOVE
指定されたオフセットのデータを、指定されたデータ(32KB未満)と置換します。 FRAGMENT_REPLACE

ノート:

DBMS_LOBパッケージは、LOBに対する豊富な操作セットを提供します。これらの操作の一部が提供されていない別のプログラム・インタフェースを使用している場合は、DBMS_LOBパッケージの対応するPL/SQLプロシージャまたは関数をコールします。

次の各項のほとんどのコード例では、次の構造のprint_media表を使用しています。

図9-1 print_media表

print_media表