4 値LOB
値LOBは、一時LOBのサブセットであり、自律型で、読取り専用で、より高パフォーマンスです。
- 値LOBについて
LOBに対する読取りおよび書込みを必要とするアプリケーションでは、参照LOBと呼ばれる永続LOBおよび一時LOBを使用します。 - 値LOBを使用する場合
多くのアプリケーションでは、LOBを使用して中規模オブジェクト、約数MBのサイズを格納し、SQL問合せのコンテキストでLOB値を読み取る必要があります。 - 値LOBの作成
値LOBは、SQL文によって生成される読取り専用一時LOBで、次のSQLフェッチ時に自動処理されます。値LOBは、SQLからフェッチされたLOBは次のフェッチの実行前にしか読み取られないというシナリオの場合のみ使用します。 - 問合せの値LOB
問合せが値をフェッチするか、参照LOBをフェッチするかはコンパイル時の決定であり、問合せのdescribeを使用して取得できます。 - QUERY AS VALUEを使用したLOBに対するDML操作の実行
QUERY AS VALUEプロパティはSQL問合せにのみ適用できるため、表に対するDMLには影響しません。したがって、INSERT
やUPDATE
などのすべてのDMLは、QUERY AS VALUEまたはQUERY AS REFERNCEとして宣言されたLOB列に対して同様に機能します。 - 様々なプログラム・インタフェースでのLOB APIの値
この項では、様々なプログラム・インタフェースでのLOB固有のAPI値を示します。 - 値LOBの制限
値LOBの操作中は、次の制限に留意してください。
4.1 値LOBについて
LOBに対する読取りおよび書込みを必要とするアプリケーションの場合は、永続LOBと一時LOB(これ以降では、参照LOBと呼ぶ)を使用します。
多くのアプリケーションでは、中規模オブジェクト(サイズが数MB程度)の格納にLOBが使用されるため、SQL問合せのコンテキストにおいてのみLOB値を読み取る必要があります。アプリケーションで大きいVARCHAR
またはRAW
データ型としてLOBを使用する場合には、値LOBを使用することをお薦めします。
値LOBには、次の特性があります。
-
値LOBは、参照LOBに比べてパフォーマンスと管理性が高くなるように最適化された、特殊な種類の読取り専用一時LOBです。
-
値LOBでは、すべてのLOB読取りAPIがサポートされていますが、書込みAPIはサポートされません。LOB読取りAPIでは、データをピース単位で読み取ることができ、操作の量とオフセットをユーザーが指定できるようにすることでランダム・アクセスをサポートできます。
-
カーソルに対して次のフェッチが実行されると、値LOBが自動的に解放されます。一時LOBの場合、アプリケーションでそれに対する処理が完了したときのその一時LOBの解放は、ユーザーが実行する必要があります。
substr
、to_clob()
など、いくつかのSQL演算子では一時LOBが作成されますが、これらの一時LOBの解放はユーザーが実行する必要があります。一時LOBを解放しないと、システムの速度が大幅に低下する可能性があります。値LOBの場合、ユーザーはVARCHAR32k
データ型に似たLOBを使用でき、ユーザーがそれらを解放する必要はありません。Oracle Databaseにより、SQLで次の行セットがフェッチされるとすぐに、自動的にLOBが解放されます。フェッチ期間のこの概念はSQLの場合のみ存在するため、値LOBはSQL問合せのコンテキストにおいてのみ存在します。 -
値LOBは、参照LOBと同様に、任意のサイズに設定できます。
値LOBではすべてのLOB読取りAPIがサポートされているため、LOBサイズに制限はありません。ただし、値LOBは、サイズが数MBまでのドキュメント(これはクライアントにプリフェッチできる)に最適です。
-
値LOBは、ほとんどの場合、参照LOBよりもパフォーマンスが高速です。アプリケーションでSQL問合せの一部として読取りのためにLOBがフェッチされ、そのカーソルに対して次のフェッチが実行される前にそのLOBデータが使用される場合は、値LOBを使用することをお薦めします。
-
PL/SQLには、値LOBの概念がありません。
値LOBは、SQL問合せにおいてと、JDBC、OCI、ODP.NETなどのクライアント側プログラム・インタフェースにおいて存在します。PL/SQLでは、一時LOBは、そのLOBを含む変数をユーザーが上書きすると自動的に解放されます。したがって、SQLからPL/SQLに渡された値LOBは、読取り専用一時LOBに変換され、その持続期間は、そのLOBを保持する変数の持続期間になります。詳細は、値LOB用のPL/SQL APIを参照してください。
親トピック: 値LOB
4.2 値LOBを使用する場合
多くのアプリケーションでは、中規模オブジェクト(サイズが数MB程度)の格納にLOBが使用されるため、SQL問合せのコンテキストにおいてのみLOB値を読み取る必要があります。
VARCHAR
またはRAW
データ型としてLOBを使用する場合には、値LOBを使用することをお薦めします。すべてのLOB読取りは、次のSQL行セットがフェッチされる前に実行されます。これは、次のSQL行セットをフェッチした後に値LOBコンテンツにアクセスする必要がある場合は、その値LOBコンテンツをクライアント側で読み取って保存する必要があるということです。
次のシナリオでは永続LOBと一時LOBを使用することをお薦めします。
- LOBに対する読取りと書込みを必要とするアプリケーションの場合
- LOBが長期間存続することが予想される場合
- クライアント側でLOBコンテンツを完全に読み込んでキャッシュすることができず、LOBロケータを使用してサーバーからLOBデータを読み込む場合
注意:
参照LOB列を値LOB列に変換する前に、ビジネス・ユース・ケースで値LOBを使用する必要があることを確認してください。親トピック: 値LOB
4.3 値LOBの作成
値LOBは、読取り専用一時LOBであり、SQL文によって生成され、次のSQLフェッチで自動解放されます。値LOBは、SQLからフェッチされたLOBは次のフェッチの実行前にしか読み取られないというシナリオの場合のみ使用します。
値LOBは、そのオリジンに関係なく必ず一時LOBです。そのカーソルに対して次のフェッチが実行されると、Oracleサーバーにより、前のフェッチの値LOBが自動的に解放されます。そのため、前のフェッチの値LOBにはアクセスできません。値LOBは使い捨て可能なLOBとみなすことができます。それを読み取った後、それは不要になり、解放されます。これにより、一時LOBの蓄積を防ぐことができ、問合せのパフォーマンスとスケーラビリティが向上します。
SQL問合せでは、次の方法で値LOBを作成できます。
次の項のほとんどの例では、agents
表を使用します。次に、agents
表の構造を示します。
列名 | 列の型 |
---|---|
ID |
NUMBER |
NAME |
VARCHAR2(100) |
VALUELOB |
CLOB VALUE |
REFERENCELOB |
CLOB |
CV |
BLOB |
PHOTO |
BLOB VALUE |
- DDLを使用した値LOBの作成
特定の表のすべてのLOBが値LOBのユースケースに従うようにアプリケーションが記述されている場合は、CREATE TABLE
文またはALTER TABLE
文の一部としてLOB列のquery as value
構文を使用します。 - SQL演算子を使用した値LOBの作成
次の例に示すように、LOB入力とLOB出力を持つSQL演算子は、入力が値LOBである場合に値LOBを生成します。 - LOB_VALUE演算子を使用した値LOBの作成
次の例に示すように、LOB_VALUE
演算子を使用して、永続LOBまたは一時LOBを値LOBに変換できます。 - ビューでの値LOBの作成
QUERY AS VALUEプロパティを持つLOB列は、ビューの一部にできます。それらは2つの方法で作成できます。
親トピック: 値LOB
4.3.1 DDLを使用した値LOBの作成
特定の表のすべてのLOBが値LOBユースケースに準じるようにアプリケーションが記述されている場合は、CREATE TABLE
文またはALTER TABLE
文の一部としてそのLOB列用にquery as value
構文を使用します。
これにより、アプリケーションの残りの部分を変更することなく、指定した列から値としてすべてのLOBロケータがフェッチされます。表作成の場合のデフォルトはquery as reference
であり、LOBロケータが参照LOB(永続または一時)としてフェッチされます。
例
次の例では、値LOBであるvaluelob
およびphoto
など、様々なLOB型の列を含むagentという名前の表を作成します。
create table agents (id number, name varchar2(100), valuelob clob, referencelob clob, cv blob)
lob(valuelob) query as value;
alter table agents add (photo blob) lob(photo) query as value;
次の例では、ALTER TABLE MODIFY LOB
句を使用してLOB列の問合せプロパティのvalue
とreference
とを切り替える方法を示します。
alter table agents modify lob(cv) query as value;
ノート:
query as value
またはquery as reference
プロパティは、問合せでのLOBの選択方法にのみ影響します。LOBを表に物理的に格納する方法は変わりません。
表を記述するときに、query as value
付きで定義された列には、そのデータ型にVALUE
キーワードが含まれます。
SQL> desc agents;
Name Null? Type
--------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(100)
VALUELOB CLOB VALUE
REFERENCELOB CLOB
CV BLOB
PHOTO BLOB VALUE
次の例では、query as value
プロパティ付きで定義された列に対して問合せを実行すると、値LOBが返されます。
select valuelob from agents;
ノート:
query as value
プロパティはLOBロケータにのみ適用できるため、LOBのデータ・インタフェースには影響しません。つまり、query as reference
およびquery as value
付きで宣言されたLOBでの、データ・インタフェースの動作には違いはありません。
親トピック: 値LOBの作成
4.3.2 SQL演算子を使用した値LOBの作成
次の例で示すように、LOB入力およびLOB出力を含むSQL演算子では、入力が値LOBの場合には値LOBが生成されます。
-- Produces a value LOB
SELECT SUBSTR(valuelob, 5, 5) from agents;
-- Produces a value LOB
SELECT to_blob(valuelob, 0) from agents;
-- Produces a value LOB
SELECT CONCAT(valuelob, valuelob) from agents;
LOB入力およびLOB出力を含むSQL演算子では、入力が参照LOBの場合、または入力がLOB型でない場合は、次の例に示すように、旧式の一時LOBが生成されます。
-- Produces a reference Temporary LOB
SELECT SUBSTR(referencelob, 5, 5) from agents;
-- Produces a reference Temporary LOB
SELECT to_blob(substr(referencelob,5,5), 0) from agents;
-- Produces a reference Temporary LOB as name is varchar type
SELECT to_clob(name) from agents;
1つのSQL演算子に2つのLOBが含まれており、その一方が値LOBで他方が値LOBでない場合は、次の例のようにエラーが発生します。
-- Raises an error
SELECT CONCAT(valuelob, referencelob) from agents;
親トピック: 値LOBの作成
4.3.3 LOB_VALUE演算子を使用した値LOBの作成
次の例で示すように、LOB_VALUE
演算子を使用すると、永続LOBまたは一時LOBを値LOBに変換できます。
-- Produces a value LOB
SELECT lob_value(referencelob) from agents;
-- Produces a value LOB
SELECT lob_value(substr(referencelob, 2, 10)) from agents;
-- Produces a value LOB
SELECT lob_value(to_clob(name)) from agents;
LOB_VALUE()
演算子は、表内のLOB列を、その列に対する様々な問合せでLOBを参照または値として選択する必要があるためにQUERY AS VALUE
として設定できない場合に役立ちます。この演算子により、参照LOBを値LOBに変換して、値LOBによって提供されるパフォーマンス上の利点を活用します。
PL/SQL関数では、値LOBは生成されません。PL/SQL関数から値LOBを取得するには、次の例で示すように、PL/SQL関数の出力に対してLOB_VALUE()
演算子を使用します。
-- Produces a value LOB
SELECT LOB_VALUE(lob_producing_plsql_function(...)) from table;
ノート:
値LOBから参照LOBへの逆変換は許可されていません。
親トピック: 値LOBの作成
4.3.4 ビュー内の値LOBの作成
QUERY AS VALUEプロパティが指定されたLOB列は、ビューの一部にできます。それらは2つの方法で作成できます。
ビュー列で値LOB列が参照されている場合、ビュー列も値LOBになります。次の例では、valuelob_v
列を、ビューに含まれる値LOBにする方法を示します。
-- valuelob_v column is a value LOB column
create view agents_v as
select id id_v, valuelob valuelob_v from agents;
値LOBを返すSQL/LOB演算子がビューの列で使用されている場合、その列は値LOBになります。
-- valuelob_v2 column is a value LOB
create view agents_v2 as
select id id_v2, substr(valuelob, 5, 5) valuelob_v2 from agents;
-- valuelob_v3 column is a value LOB
create view agents_v3 as
select id id_v3, lob_value(referencelob) valuelob_v3 from agents;
-- valuelob_v4 column is a value LOB
create view agents_v4 as
select id id_v4, lob_value(substr(referencelob, 5, 5)) valuelob_v4 from agents;
SQLPLUSのdescribeコマンドでは、ビューのLOB列が値LOBであるかどうかが示されます。
SQL> desc agents_v;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID_V NUMBER
NAME_V VARCHAR2(100)
VALUELOB_V CLOB VALUE
SQL> desc agents_v2;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID_V2 NUMBER
NAME_V2 VARCHAR2(100)
VALUELOB_V2 CLOB VALUE
親トピック: 値LOBの作成
4.4 問合せにおける値LOB
問合せで値LOBがフェッチされるか参照LOBがフェッチされるかは、コンパイル時に決定され、その問合せに関する記述を使用することで把握できます。
例: 値LOBの実行計画
実行計画の出力では、計画内の値LOBについては、/* LOB_BY_VALUE */というヒントが示されます。
SQL> explain plan for select valuelob, substr(valuelob, 5, 5) from agents;
...
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2002 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| AGENTS | 1 | 2002 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
...
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "VALUELOB" /*+ LOB_BY_VALUE */ [LOB,4000]
...
例: LOB_BY_VALUEのない参照LOBの実行計画
SQL> explain plan for select referencelob, substr(referencelob, 5, 5) from agents;
...
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2002 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| AGENTS | 1 | 2002 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
...
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "REFERENCELOB"[LOB,4000]
...
特定の状況では、Oracleサーバーによって自動的に、LOBを値LOBとして選択する必要があると判断されます。
例: 値LOBへの自動変換が示されている実行計画
SQL> explain plan for select length(referencelob) from agents;
...
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2002 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| AGENTS | 1 | 2002 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
...
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "REFERENCELOB" /*+ LOB_BY_VALUE */ [LOB,4000]
...
4.5 QUERY AS VALUEが指定されたLOBに対するDML操作の実行
QUERY AS VALUEプロパティは、SQL問合せの場合のみ適用できます。そのため、それは表に対するDMLには影響しません。したがって、INSERT
やUPDATE
などのすべてのDMLは、QUERY AS VALUEまたはQUERY AS REFERNCEとして宣言されたLOB列に対して同様に機能します。
DMLのRETURNING
ユーザーがLOBロケータに対して、RETURNING句を指定してDMLを実行した場合、返されるLOBロケータは、LOB列のQUERY ASプロパティに関係なく、参照LOBになります。したがって、次の例で示すように、ユーザーはRETURNING句を指定してempty_lob()
をINSERTし、戻されたロケータを使用して永続LOBに書き込むことができます。
-- insert with returning clause
declare
c clob;
begin
-- returns a reference to the persistent LOB
insert into agents values (1, 'My Name', empty_clob(), NULL, NULL, NULL)
returning valuelob into c;
-- updates the persistent LOB
dbms_lob.writeappend(c, length('I am a value LOB'), 'I am a value LOB');
end;
/
SELECTのFOR UPDATE
同様に、ユーザーがFOR UPDATE
句を指定してロケータを選択する場合、その目的は、そのLOB列に格納されている永続LOBを更新することです。そのため、次の例で示すように、返されたLOBロケータは、そのLOB列のQUERY ASプロパティに関係なく参照LOBになります。
-- Select for update
declare
c clob;
begin
-- returns a reference to the persistent LOB
select valuelob into c from agents where id = 1 for update;
-- This updates the persistent LOB
dbms_lob.writeappend(c, length('!!!'), '!!!');
end;
/
親トピック: 値LOB
4.6 様々なプログラム・インタフェースでの値LOB API
この項では、様々なプログラム・インタフェースにおけるLOB固有のAPIの値をリストします。
- 値LOBのプリフェッチ
クライアント側で大きいLOBプリフェッチ・サイズを設定すると、サーバーへのラウンド・トリップが回避され、値LOBのパフォーマンスが大幅に向上します。 - 値LOB APIのサポート
LOB変数が永続LOBロケータまたは一時LOBロケータで初期化されると、LOBに対する後続の読取り操作は、DBMS_LOB
パッケージのサブプログラムなどのAPIを使用して実行できます。 - 値LOBのPL/SQL API
この項では、値LOBで使用されるPL/SQL APIについて説明します。 - 値LOBのOCI API
この項では、値LOBで使用されるOCI APIについて説明します。 - 古いクライアントとの相互運用性
バージョン21c以前のクライアントに値LOBを送信すると、値LOBは読取り専用の一時参照LOBに変換されます。
親トピック: 値LOB
4.6.1 値LOBのプリフェッチ
クライアント側で大きいLOBプリフェッチ・サイズを設定すると、サーバーへのラウンドトリップが回避され、値LOBのパフォーマンスが大幅に向上します。
JDBC、OCIおよびODP.NETにおける値LOBのデフォルトのLOBプリフェッチ・サイズは、32kです。
ノート:
OCIでは、LOBプリフェッチ・サイズを0に設定すると、Oracleにより、値LOBの場合はプリフェッチ・サイズが32k、参照LOBの場合は0と解釈されます。LOBプリフェッチ・サイズのその他の設定は、値LOBの場合でも参照LOBの場合でも受け入れられます。
値LOBについては、LOB読取りサイズの80%以上に対応できる大きさのLOBプリフェッチ・サイズを設定することをお薦めします。
関連項目:
LOBデータおよびLOB長のプリフェッチ親トピック: 様々なプログラム・インタフェースでのLOB APIの値
4.6.2 値LOB APIのサポート
LOB変数が永続LOBロケータまたは一時LOBロケータで初期化されると、LOBに対する後続の読取り操作は、DBMS_LOB
パッケージのサブプログラムなどのAPIを使用して実行できます。
関連項目:
LOB API値LOBでサポートされている操作は、次のカテゴリに分けられます。
表4-1 値LOB APIでサポートされている操作
分類 | 値LOBの動作 |
---|---|
健全性チェック | サポート対象 |
オープンとクローズ | オープンは、読取り専用モードにおいて許可されています。読取り/書込みが指定されている場合は、エラーがスローされます。 |
読取り操作 | サポート対象 |
変更操作 | 値LOBは読取り専用であるため、サポートされていません。 |
複数のロケータを含む操作 | OCILobLocatorAssign() はサポートされていません。
|
OCILobLocatorAssign がサポートされていないため、OCILobIsEqual() では必ずFALSE が返されます。
|
|
OCILobAppend() 、OCILobCopy2() およびOCILobLoadFromFile2() : これらの操作では、値LOBはソースLOBとしてサポートされています。変換先LOBにはFOR UPDATE が選択されている必要があり(これにより、それが参照LOBに変換される)、それにより、その操作の実行が許可されます。変換先LOBを値LOBにはできません。
|
|
SecureFilesに固有の操作 | 値LOBは一時LOBでありSecureFilesではないため、サポートされていません。 |
一時LOBに固有の操作 | CreateTemporary では値LOBを生成できません。
値LOBは自動的に解放されるため、 |
親トピック: 様々なプログラム・インタフェースでのLOB APIの値
4.6.3 値LOB用のPL/SQL API
この項では、値LOBと一緒に使用されるPL/SQL APIについて説明します。
値LOBは、SQL問合せにおいてと、JDBC、OCI、ODP.NETなどのクライアント側プログラム・インタフェースにおいて存在します。PL/SQLでは、一時LOBは、そのLOBを含む変数をユーザーが上書きすると自動的に解放されます。したがって、SQLからPL/SQLに渡された値LOBは、読取り専用一時LOBに変換され、その持続期間は、そのLOBを保持する変数の持続期間になります。その変数がスコープ外になると、その一時LOBが自動的に解放されます。
つまり、PL/SQLにおいては値LOBはありません。PL/SQLにおけるすべてのLOBは参照LOBです。値LOBは、SQLからPL/SQLに送信されると、読取り専用一時LOBになります。このLOBでは、表4-1にリストしたAPIがサポートされています。このLOBは、PL/SQLからJDBCやOCIなどのクライアントに渡された場合は、引き続き、読取り専用一時LOBとなります。つまり、それは表4-1と同じAPIサポートに準じていますが、そのカーソルに対して次のフェッチが実行されても自動的には解放されません。このLOBに対してそれが実行された後は、ユーザーがこのLOBを解放する必要があります。
例4-1 値LOB用のPL/SQL API
次の例では、PL/SQL関数の出力に対してLOB_VALUE
演算子を使用することで値LOBを作成する方法を示します。
SELECT LOB_VALUE(lob_producing_plsql_function(...)) from table;
OUTバインド
OUT
バインドは、SQL問合せの一部ではないため、値LOBを返すことができません。値LOBをOUT
バインド変数として返そうとすると、その値LOBは読取り専用一時LOBに変換されます。そのLOBは参照LOBであるため、それを使用した後にアプリケーション開発者が解放する必要があります。なお、LOB_VALUE
演算子はOUT
バインドでは機能しません。
親トピック: 様々なプログラム・インタフェースでのLOB APIの値
4.6.4 値LOB用のOCI API
この項では、値LOBと一緒に使用されるOCI APIについて説明します。
例4-2 OCIDescribeAnyを使用して表でのOCI_ATTR_LOB_IS_VALUEを返す明示的な記述
void explicitDescribe()
{
/* Assume: create table lobtab (c clob) lob(c) query as value */
ub1 isValueLob = 0;
OCIParam *colhd;
OCIParam *paramp = NULL;
OCIParam *lstHandle = NULL;
text *table = "lobtab";
OCIDescribe *dschp = NULL;
OCIHandleAlloc(envhp, (void **)&dschp, OCI_HTYPE_DESCRIBE, 0, NULL);
checkerr(errhp, OCIDescribeAny(svchp, errhp, (void *)table, strlen(table),
OCI_OTYPE_NAME, 0, OCI_PTYPE_TABLE, dschp));
checkerr(errhp, OCIAttrGet((dvoid *) dschp, (ub4) OCI_HTYPE_DESCRIBE,
(dvoid *)¶mp, (ub4*)0, (ub4)OCI_ATTR_PARAM, errhp));
/* Get the number of columns */
checkerr(errhp, OCIAttrGet((void *)paramp, OCI_DTYPE_PARAM, (void *)&noofcols,
(ub4 *)0, OCI_ATTR_NUM_COLS, errhp));
/* Get the column list. */
checkerr(errhp, OCIAttrGet(paramp, OCI_DTYPE_PARAM, &lstHandle, 0,
OCI_ATTR_LIST_COLUMNS, errhp));
/* Go through the column list */
for (int i = 1; i <= noofcols; i++)
{
/* Get parameter for column i */
checkerr(errhp, OCIParamGet(lstHandle, OCI_DTYPE_PARAM,
(OCIError *)errhp, (void**)&colhd, (ub4)i),
(text *)"param get");
isValueLob = 0;
checkerr(errhp,OCIAttrGet(colhd, OCI_DTYPE_PARAM,
&(isValueLob), 0,
OCI_ATTR_LOB_IS_VALUE,
(OCIError *)errhp),
(text*)"attr get");
printf("Is value lob = %d\n",isValueLob); /* Expected output: Is value lob = 1 */
}
...
}
例4-3 問合せの列ハンドルでOCI_ATTR_LOB_IS_VALUEを返す暗黙的な記述
text *select_sql = (text *)"select valuelob from agents"; /* generates value LOB */
OCILobLocator *lob1;
Boolean isValLob = 0;
OCIParam *colhd;
/* Prepare select statement */
checkerr(errhp, OCIStmtPrepare(stmthp, errhp, select_sql, /* select valuelob from agents */
(ub4) strlen((char *) select_sql), ...);
/* Execute select statement */
checkerr(errhp, OCIStmtExecute(svchp, stmthp, errhp, ...);
/* Implicit Describe: Get parameter for select item #1 */
checkerr(errhp, OCIParamGet(stmthp, OCI_HTYPE_STMT,
(OCIError *)errhp,
(void**)&colhd, (ub4)1),
(text *)"param valuelob column");
/* Check if colhd (valulob column) returns value LOB */
checkerr(errhp,OCIAttrGet(colhd, OCI_DTYPE_PARAM,
&(isValueLob), 0,
OCI_ATTR_LOB_IS_VALUE,
(OCIError *)errhp),
(text *)"attr get");
例4-4 LOBロケータのフェッチ後のOCI_ATTR_LOB_IS_VALUEの確認
void CheckValue(OCILobLocator *lob1)
{
boolean isValLob = 0;
/* Check if lob1 is value LOB */
OCIAttrGet(lob1, OCI_DTYPE_LOB, &isValLob, sizeof(boolean),
OCI_ATTR_LOB_IS_VALUE, errhp);
}
例4-5 LOBロケータのフェッチ後のOCI_ATTR_LOB_IS_READONLYの確認
PL/SQLには値LOBは存在しないということを思い出してください。値LOBは、SQLからPL/SQLに送信されると、読取り専用一時LOBになります。このLOBは、表4-1と同じAPIサポートに従います。このLOBは、PL/SQLからJDBCやOCIなどのクライアントに渡された場合は、引き続き、読取り専用一時LOBとなります。次の例では、OCI_ATTR_LOB_IS_READONLY
属性を使用することでLOBロケータの読取り専用プロパティを確認する方法を示します。
void CheckReadOnly(OCILobLocator *lob1)
{
boolean isReadOnly = 0;
/* Check if lob1 is read-only */
OCIAttrGet(lob1, OCI_DTYPE_LOB, &isReadOnly, sizeof(boolean),
OCI_ATTR_LOB_IS_READONLY, errhp);
}
親トピック: 様々なプログラム・インタフェースでのLOB APIの値
4.6.5 古いクライアントとの相互運用性
値LOBをバージョン21c以前のクライアントに送信すると、その値LOBは読取り専用の一時参照LOBに変換されます。
つまり、それは<4.4.2のカテゴリ表>と同じAPIサポートに準じていますが、そのカーソルに対して次のフェッチが実行されても自動的には解放されません。このLOBに対してそれが実行された後は、ユーザーがこのLOBを解放する必要があります。
親トピック: 様々なプログラム・インタフェースでのLOB APIの値
4.7 値LOBに関する制限事項
値LOBを使用する際には、次の制限事項に留意してください。
- 値LOBは読取り専用LOBであるため、それらに対する変更操作は実行できません。
OCILobLocatorAssign()
などのロケータ割当て操作は、値LOBではサポートされていません。- 値LOBは、JDBCで次の操作ではサポートされていません。
- クライアント側の結果キャッシュ
- 値LOBは、OCIにおける次の操作ではサポートされていません。
- スクロール可能カーソル
- クライアント側の結果キャッシュ
- 値LOBを、問合せにおいて同じ操作で参照LOBと組み合せることはできません。次に例を示します。
select concat(valuelob, referencelob) from agents; -- Error expected
親トピック: 値LOB