2 LOBの作業
アプリケーションを開発するためにLOBを操作するには、LOBのセマンティクスとLOBで使用される様々な方法について理解する必要があります。
永続LOBに関するほとんどの説明は、既存の表にあるLOBを扱うことを前提としています。通常、LOB列を含む表の作成作業は、データベース管理者が行います。
関連項目:
-
SecureFilesパラダイムを使用したLOBの作成については、「Oracle LOB記憶域の使用」を参照してください
-
LOBの作成に使用される記憶域パラメータについては、「アプリケーションでのLOB記憶域」を参照してください
トピック:
- LOB列の状態
LOB列のセルにアクセスするときに使用する手法は、そのセルの状態によって異なります。 - LOBを含む行のロック
LOBを含む行をロックして、トランザクション中に他のデータベース・ユーザーがLOBに書き込むのを防止できます。 - LOBのオープン操作とクローズ操作
LOB APIには、LOBインスタンスを明示的にオープンおよびクローズできる操作が含まれます。 - LOBロケータおよびLOB値
2つの異なる方法を使用して、LOB値にアクセスして変更できます。 - LOBロケータとBFILEロケータ
LOB型BLOB、CLOBおよびNCLOBのロケータのセマンティクスとBFILE型のロケータのセマンティクスの間には違いがあります。 - LOBアクセス
- LOBのルールと制限
この項では、LOBのルールと制限の詳細を説明します。
親トピック: スタート・ガイド
2.1 LOB列のステータス
LOB列のセルにアクセスするときに使用する手法は、そのセルの状態に応じて異なります。
LOB列のセルの状態は、次のいずれかです。
-
NULL
表セルは作成されていますが、セルに値またはロケータは保持されていません。
-
空
セルにロケータを含むLOBインスタンスが存在しますが、値はありません。LOBの長さは0(ゼロ)です。
-
移入済
セルにはロケータと値を含むLOBインスタンスが存在します。
親トピック: LOBの操作
2.2 LOBを含む行のロック
LOBを含む行をロックして、トランザクション中に他のデータベース・ユーザーがLOBに書き込むのを防止できます。
-
行をロックするには、行の選択時に
FOR UPDATE句を指定します。行をロックすると、トランザクションを終了するまで他のユーザーはそのLOBをロックまたは更新できません。
親トピック: LOBの操作
2.3 LOBのオープン操作とクローズ操作
LOB APIには、LOBインスタンスを明示的にオープンおよびクローズできる操作が組み込まれています。
永続LOBインスタンスは、BLOB、CLOB、NCLOBまたはBFILEなど、どの型の場合にもオープンおよびクローズできます。LOBをオープンすると、次の一方または両方の結果となります。
-
LOBを読取り専用モードでオープンした場合
この場合、LOB(LOBロケータとLOB値の両方)は、明示的にクローズするまではセッションで変更できません。たとえば、このモードでオープンすることで、重要な操作でLOBを使用しているときに、そのLOBがプログラムの他の部分により変更されないようにできます。操作の実行後に、LOBをクローズできます。
-
LOBを読取り/書込みモードでオープンした場合(通常の
BLOB、CLOBまたはNCLOBインスタンスのみ)LOBを読取り/書込みモードでオープンすると、そのLOBをクローズするまでLOB列の索引メンテナンスが遅延されます。このモードでのLOBのオープンが役立つのは、LOB列に拡張可能索引があり、そのLOBに書込みを行うたびにデータベースで索引メンテナンスが実行されるのを避ける場合のみです。オープンしているLOBに対して複数の書込み操作を実行する場合は、この方法でオープンするとアプリケーションのパフォーマンスを改善できます。
オープンしたLOBは、セッションのいずれかの時点でクローズする必要があります。これは、オープンしているLOBに対する唯一の要件です。LOBインスタンスがオープンしている間は、オープン時のモードで許可されている操作であれば、LOBに対して必要な数の操作を実行できます。
関連項目:
これらのAPIの使用方法の詳細は、「OPENおよびCLOSEインタフェースを使用した永続LOBのオープン」を参照してください
親トピック: LOBの操作
2.4 LOBロケータとLOB値
- LOB用データ・インタフェースの使用
OCIのLOB用データ・インタフェースを使用すると、CアプリケーションでCLOB列とBLOB列に対してバインド操作と定義操作を実行できます。 - LOBロケータを使用したLOB値へのアクセスと変更
LOBロケータを使用して、LOB値にアクセスして変更できます。
親トピック: LOBの操作
2.4.1 LOB用データ・インタフェースの使用
OCIのLOB用データ・インタフェースを使用すると、CアプリケーションでCLOB列とBLOB列に対してバインド操作と定義操作を実行できます。
データ・インタフェースを使用すると、次のように、LOBロケータを使用せずにLOB列にデータを挿入したり、LOB列からデータを選択できます。
-
LOB列に関連付けられているバインド変数を使用して、
CLOBに文字データを挿入するか、BLOBにRAWデータを挿入します。 -
定義操作を使用してアプリケーションで出力バッファを定義します。このバッファに、
CLOBから選択された文字データまたはBLOBから選択されたRAWデータが保持されます。関連項目:
LOBの他のデータ型への暗黙的な割当ての詳細は、「永続LOB用のデータ・インタフェース」を参照してください
親トピック: LOBロケータとLOB値
2.4.2 LOBロケータを使用したLOB値へのアクセスと変更
LOBロケータを使用して、LOB値にアクセスして変更できます。
LOBの場所に対する参照であるLOBロケータは、データベースに格納されているインスタンス化されたLOBの値にアクセスできます。データベース表では、CLOB、BLOB、NCLOBおよびBFILE列にロケータのみが格納されます。
LOBロケータとLOB値に関する注意事項は、次のとおりです。
-
LOBロケータは、LOB値をアクセスまたは操作するために様々なLOB APIに渡されます。
-
LOBロケータは、同じ型の任意のLOBインスタンスに割り当てることができます。
-
LOBインスタンスは一時または永続として特徴付けられますが、ロケータはそのように特徴付けられません。
親トピック: LOBロケータとLOB値
2.5 LOBロケータとBFILEロケータ
LOB型BLOB、CLOBおよびNCLOBのロケータのセマンティクスとBFILE型のロケータのセマンティクスの間には違いがあります。
-
LOB型の
BLOB、CLOBおよびNCLOBの場合、LOB列にはLOB値のロケータが格納されます。各LOBインスタンスは固有のLOBロケータのみでなく、LOB値の固有のコピーも持ちます。 -
初期化済の
BFILE列の場合、行にはBFILEの値を保持する外部オペレーティング・システム・ファイルのロケータが格納されます。行内の各BFILEインスタンスは固有のロケータを持ちますが、2つの異なる行に同じオペレーティング・システム・ファイルを指すBFILEロケータを含めることも可能です。
LOB値の格納場所に関係なく、ロケータは初期化済LOB列の表の行に格納されます。また、表からLOBを選択した場合、戻されるLOBは常に一時LOBです。
ノート:
単にロケータという場合は、LOBロケータとBFILEロケータの両方を指します。
関連項目:
一時LOBのロケータの詳細は、「SQLファンクションから戻されるLOB」を参照してください
トピック:
- LOBの例の表: PMスキーマのprint_media表
Oracle LOBの例の多くでは、Oracle Databaseサンプル・スキーマPMの表print_mediaを使用しています。 - LOB列の初期化
NULLであるLOBインスタンスには、ロケータがありません。
親トピック: LOBの操作
2.5.1 LOBの例の表: PMスキーマのprint_media表
Oracle LOBの例の多くでは、Oracle Databaseサンプル・スキーマPMの表print_mediaを使用しています。
print_media表は、次のように定義されます。
CREATE TABLE print_media
( product_id NUMBER(6)
, ad_id NUMBER(6)
, ad_composite BLOB
, ad_sourcetext CLOB
, ad_finaltext CLOB
, ad_fltextn NCLOB
, ad_textdocs_ntab textdoc_tab
, ad_photo BLOB
, ad_graphic BFILE
, ad_header adheader_typ
) NESTED TABLE ad_textdocs_ntab STORE AS textdocs_nestedtab;関連項目:
print_mediaおよびそれに関連付けられた表とファイルの作成の詳細は、「1つ以上のLOB列を含む表の作成」を参照してください
親トピック: LOBロケータとBFILEロケータ
2.5.2 LOB列の初期化
NULLであるLOBインスタンスには、ロケータがありません。
LOBインスタンスをLOB APIルーチンに渡す前に、そのインスタンスにロケータを含める必要があります。たとえば、行からNULLのLOBを選択できますが、そのインスタンスをPL/SQL DBMS_LOB.READプロシージャには渡せません。LOBインスタンスを初期化し(これによってロケータが提供されます)、NULL以外にする必要があります。これにより、LOBインスタンスを渡すことが可能になります。
トピック:
- 永続LOB列の初期化
サポートされているプログラム環境インタフェース(PL/SQL、OCI、Visual BasicまたはJava)を使用してデータを永続LOBに書き込む前に、LOB列およびLOB属性をNULL以外にする必要があります。 - BFILEの初期化
LOB APIを使用してBFILE値にアクセスする前に、BFILE列または属性をNULL以外にする必要があります。
親トピック: LOBロケータとBFILEロケータ
2.5.2.1 永続LOB列の初期化
サポートされているプログラム環境(PL/SQL、OCI、Visual BasicまたはJava)を使用してデータを永続LOBに書き込む前に、LOB列およびLOB属性をNULL以外にする必要があります。
LOB列およびLOB属性をNULL以外にするには、BLOBに対してはEMPTY_BLOBファンクション、CLOBおよびNCLOBに対してはEMPTY_CLOBファンクションで、INSERT文およびUPDATE文を使用して永続LOBを空に初期化します。
ノート:
SQLを使用すると、NULL値が含まれているLOB列にもデータを移入できます。
関連項目:
-
LOB列の初期化方法の詳細は、「アプリケーションでのLOB記憶域」を参照してください
-
サポートされているすべてのインタフェースの詳細は、「LOBをサポートするプログラム環境」を参照してください
EMPTY_BLOB()またはEMPTY_CLOB()ファンクションを実行すること自体では例外は発生しません。ただし、空に設定されたLOBロケータを使用して、PL/SQLのDBMS_LOBまたはOCI関数でLOB値に対してアクセスまたは操作すると、例外が発生します。
空のLOBロケータを使用できるのは、INSERT文のVALUES句やUPDATE文のSET句などです。
ノート:
文字列は、インスタンス用のデフォルトの文字セットを使用して挿入されます。
次の例のINSERT文は、「LOBの例の表: PMスキーマのprint_media表」で説明されているprint_media表を使用し、次の処理を実行しています。
-
ad_sourcetextに文字列'my Oracle'を移入します -
ad_composite、ad_finaltextおよびad_fltextnを空の値に設定します -
ad_photoをNULLに設定します -
ad_graphicを、論理ディレクトリmy_directory_objectにあるmy_pictureファイルを指すように初期化します
CREATE OR REPLACE DIRECTORY my_directory_object AS 'oracle/work/tklocal';
INSERT INTO print_media VALUES (1726, 1, EMPTY_BLOB(),
'my Oracle', EMPTY_CLOB(), EMPTY_CLOB(),
NULL, NULL, BFILENAME('my_directory_object', 'my_picture'), NULL);
同様に、print_media内のad_header列のLOB属性は、次に示すようにNULL、空、または文字/生のリテラルに初期化できます。
INSERT INTO print_media (product_id, ad_id, ad_header)
VALUES (1726, 1, adheader_typ('AD FOR ORACLE', sysdate,
'Have Grid', EMPTY_BLOB()));
関連項目:
-
OCIでのLOBロケータのセマンティクスの詳細は、「OCILobLocatorポインタの割当」を参照してください
親トピック: LOB列の初期化
2.5.2.2 BFILEの初期化
LOB APIを使用してBFILE値にアクセスする前に、BFILE列または属性をNULL以外にする必要があります。
関連項目:
BFILE列の初期化方法の詳細は、「BFILEへのアクセスについて」を参照してください
親トピック: LOB列の初期化
2.6 LOBアクセス
LOBインスタンスにアクセスするには、様々な方法があります。
トピック:
- SQLを使用したLOBへのアクセス
SQLを使用してLOBにアクセスできます。 - データ・インタフェースを使用したLOBへのアクセス
データ・インタフェースを使用してLOBにアクセスできます。 - ロケータ・インタフェースを使用したLOBへのアクセス
データベースで提供されるLOB APIにLOBロケータを渡すことで、LOBインスタンスにアクセスして操作できます。
親トピック: LOBの操作
2.6.1 SQLを使用したLOBへのアクセス
LOBにはSQLを使用してアクセスできます。
LOBデータ型を使用する列に対するサポートは、多数のSQLファンクションに組み込まれているため、SQLセマンティクスを使用してLOB列にアクセスできます。ほとんどの場合は、VARCHAR2列に使用するのと同じSQLセマンティクスをLOB列に対して使用できます。
関連項目:
LOBに対するSQLセマンティクスのサポートの詳細は、「SQLセマンティクスとLOB」を参照してください
親トピック: LOBアクセス
2.6.2 データ・インタフェースを使用したLOBへのアクセス
LOBにはデータ・インタフェースを使用してアクセスできます。
OCIやPL/SQLインタフェースのLONG-to-LOB APIを使用すると、直接LOBを選択してCHARバッファまたはRAWバッファに移動できます。次のPL/SQLの例では、ad_finaltextがVARCHAR2バッファfinal_adに移動するように選択されています。
DECLARE
final_ad VARCHAR2(32767);
BEGIN
SELECT ad_finaltext INTO final_ad FROM print_media
WHERE product_id = 2056 and ad_id = 12001 ;
/* PUT_LINE can only output up to 255 characters at a time */
...
DBMS_OUTPUT.PUT_LINE(final_ad);
/* more calls to read final_ad */
...
END;関連項目:
データ・インタフェースを使用してLOBにアクセスする方法の詳細は、「永続LOB用のデータ・インタフェース」を参照してください
親トピック: LOBアクセス
2.6.3 ロケータ・インタフェースを使用したLOBへのアクセス
データベースで提供されるLOB APIにLOBロケータを渡すことで、LOBインスタンスにアクセスして操作できます。
LOBインスタンスにアクセスするには、サポートされている各プログラム環境で用意されている広範囲なLOB APIセットを使用します。OCIの場合、LOBロケータはLOB値へのアクセスに使用されるロケータ・ポインタにマップされます。
ノート:
OCIを含め、どの環境の場合も、LOB APIはLOB値を暗黙的に操作することに注意してください。LOBロケータの間接参照先へアクセスして操作する必要はありません。
関連項目:
-
OCIでのLOBロケータのセマンティクスの詳細は、「OCILobLocatorポインタの割当」を参照してください
親トピック: LOBアクセス
2.7 LOBのルールと制限
2.7.1 LOB列のルール
LOB列には次のルールと制限があります。
- LOBは主キー列として指定できません。
- Oracle DatabaseによるリモートLOBに対するサポートは制限されているため、リモートLOBをサポートされていない形式で使用すると、ORA-22992エラーが発生する可能性があります。
- クラスタには、キー列としてもキー列以外の列としても、LOBを含めることはできません。
- 圧縮された
VARRAYデータ型はサポートされていますが、パフォーマンスは低下します。 - 次のデータ構造は、一時インスタンスとしてのみサポートされます。この種のインスタンスはデータベース表に格納できません。
- 任意のLOB型の
VARRAY - LOB属性を持つオブジェクト型など、LOB型を含む任意の型の
VARRAY - 任意のLOB型の
ANYDATA - LOB型を含む任意の型の
ANYDATA
- 任意のLOB型の
- 問合せの
ORDERBY句やGROUPBY句または集計ファンクションには、LOB列を指定できません。 SELECT...DISTINCT文やSELECT...UNIQUE文、または結合文には、LOB列を指定できません。ただし、列のオブジェクト型にその型で定義されたMAPファンクションまたはORDERファンクションが含まれている場合、SELECT...DISTINCT文、UNIONやMINUS集合演算子を使用する問合せには、オブジェクト型列のLOB属性を指定できます。- LOBセグメントの最初の(
INITIAL)エクステントには、3つ以上のデータベース・ブロックを含める必要があります。 - 最小エクステント・サイズは14ブロックです。8Kブロック・サイズ(デフォルト)の場合は、112Kと同等になります。
AFTER UPDATEDMLトリガーの作成時には、UPDATEOF句にLOB列を指定できません。- LOB列は索引キーの一部として指定できません。ただし、ドメイン索引の索引タイプ指定には、LOB列を指定できます。また、Oracle Textを使用すると、
CLOB列に索引を定義できます。 INSERT...ASSELECT操作では、LOB列とLOB属性に最大4,000バイトのデータをバインドできます。バインド変数を指定せずにSQLを使用してある表から別の表にINSERT...ASSELECTを行う場合、長さの制限はありません。- 表に
LONG列とLOB列の両方がある場合、同一のSQL文でLONG列とLOB列の両方に4,000バイトを超えるデータをバインドすることはできません。ただし、LONG列またはLOB列のいずれか一方には、4,000バイトを超えるデータをバインドできます。
ノート:
OCI関数またはDBMS_LOBパッケージを使用して、LOB列の値またはオブジェクト型列のLOB属性を変更した場合、AFTER UPDATE DMLトリガーを定義した表では、DMLトリガーが起動されません。
関連項目:
-
SecureFilesの各機能(重複除外、圧縮および暗号化)については、「Oracle LOB記憶域の使用」を参照してください
-
リモートLOBの詳細は、「リモートLOB列の操作」を参照してください。
-
クラスタ化表、ドメイン索引およびファンクション索引における移行の制限については、「LONGからLOBへの表列の移行」を参照してください
-
SQLセマンティクスの制限については、「SQLでサポートされないLOBの使用」を参照してください
親トピック: LOBのルールと制限
2.7.2 LOB操作の制限
LOBオーサリングには、一定の制限があります。
一般的なLOBの制限は、次のとおりです。
-
SQL*Loaderでは、LOBから読み取られたフィールドは句の引数として使用できません。
-
CLOB列に対する大/小文字を区別しない検索は、多くの場合成功しません。CLOB列に対して大/小文字を区別しない検索を行うには、たとえば次のようにします。ALTER SESSION SET NLS_COMP=LINGUISTIC; ALTER SESSION SET NLS_SORT=BINARY_CI; SELECT * FROM ci_test WHERE LOWER(clob_col) LIKE 'aa%';
LOWER関数がないとSELECTは失敗します。Oracle TextまたはDBMS_LOB.INSTR()を使用すると、大/小文字を区別して検索を実行できます。 -
共有サーバー(マルチスレッド・サーバー)モードでの
BFILEのセッション移行はサポートされません。これは、オープンされたBFILEに対する操作を、共有サーバーへのコール終了後も継続できることを意味します。BFILE操作が含まれる共有サーバーのセッションは、1台の共有サーバーに限定され、サーバー間での移行はできません。 -
シンボリック・リンクは、BFILEを開くときにディレクトリ・パスまたはファイル名に使用できません。ディレクトリ・パス全体および ファイル名がチェックされ、シンボリック・リンクが見つかると、次のエラーが返されます。
ORA-22288: file or LOB operation FILEOPEN failed soft link in path
親トピック: LOBのルールと制限