9.1 始める前に
プログラム・インタフェースを使用してLOBで作業する前に、LOBロケータを使用して知っておく必要がある概念について学習します。
- LOBロケータの取得
すべてのLOB APIでは、有効なLOBロケータを入力として渡す必要があります。この項では、LOBロケータを使用してLOB変数を移入する様々な方法について説明します。 - LOBのオープン操作とクローズ操作
LOB APIには、LOBインスタンスを明示的にオープンおよびクローズできる操作が含まれます。 - チャンク境界での読取りおよび書込み
パフォーマンスを向上させるには、GETCHUNKSIZE
関数によって戻される値の倍数であるオフセットおよび量を使用してLOBの読取りおよび書込みを実行する必要があります。 - LOBデータおよびLOB長のプリフェッチ
JDBC、OCIおよびODP.NETなどのほとんどのクライアントでは、フェッチ中にLOBロケータとともにデータおよびメタデータ(長さおよびチャンク・サイズ)の一部をプリフェッチすることで、サーバー・ラウンドトリップ数を削減できます。これは、永続LOB、一時LOBおよびBFILE
に適用されます。 - 文字セットIDの取得
DBMS_LOB.LOADCLOBFROMFILE
、OCILobRead2()
およびOCILobWrite2()
などの一部のLOB APIでは、文字セットIDを入力として使用します。文字セットIDを確認するには、文字セット名を知っている必要があります。 - LOB API
LOB変数が永続LOBロケータまたは一時LOBロケータで初期化されると、LOBに対する後続の読取り操作は、DBMS_LOB
パッケージのサブプログラムなどのAPIを使用して実行できます。
親トピック: LOB用のロケータ・インタフェース
9.1.1 LOBロケータの取得
すべてのLOB APIでは、有効なLOBロケータを入力として渡す必要があります。この項では、LOBロケータを使用してLOB変数を移入する様々な方法について説明します。
- 永続LOB:最初にLOB列を含む表を作成してから、LOB列に値を挿入し、LOBロケータを選択します。LOBロケータを使用して既存のLOBを変更するには、トランザクション中に他のデータベース・ユーザーが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インスタンスを明示的にオープンおよびクローズできる操作が組み込まれています。
BLOB
、CLOB
または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インスタンスがオープンしているかどうかを示す情報は格納されません。
- トランザクションを起動するDML文の間(
SELECT ... FOR UPDATE
およびCOMMIT
を含む) - 自律型トランザクション・ブロック内
- セッションの終了前(セッションで進行中のトランザクションがない場合)。
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.LOADCLOBFROMFILE
、OCILobRead2()
およびOCILobWrite2()
などの一部のLOB APIは、入力として文字セットIDを受け取ります。文字セットIDを確認するには、文字セット名を知っている必要があります。
データベース文字セットおよび各国語文字セットとして有効な文字セット名がリストされているV$NLS_VALID_VALUES
ビューから選択できます。次に、目的の文字セット名を1つの文字列引数に指定したNLS_CHARSET_ID
ファンクションをコールします。文字セットIDが整数で戻されます。
UTF16
はデータベースまたは各国語文字セットとしては使用できませんが、LOB APIではデータベース変換のためにサポートされています。UTF16
には文字set ID = 1000
を使用し、OCIではOCI_UTF16ID
を使用できます。
関連項目:
OCIUnicodeToCharSet()
関数の詳細およびOCI構文全般の詳細は、OCIUnicodeToCharSet()を参照してください。- 異なる言語でのアプリケーションの実装の詳細は、グローバリゼーション・サポートの概要を参照してください。
親トピック: 始める前に
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 |
|
BLOB をCLOB に、またはCLOB をBLOB に変換 |
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表

親トピック: 始める前に