ここでは、次の項目について説明します。
PL/SQLでは、セマンティクスが変更されました。
注意:
特に指定のないかぎり、PL/SQLセマンティクス、CLOB
およびVARCHAR2
に関するほとんどの説明は、BLOB
およびRAW
にも該当します。説明では、BLOB
およびRAW
については特に記載しません。
PL/SQLセマンティクスのサポートは、この項で説明します。
PL/SQLでは、CLOB
からVARCHAR2
へおよびVARCHAR2
からCLOB
への暗黙的なデータ型変換が可能です。
これらの変換により、アプリケーションで次の操作を実行できます。
VARCHAR2
PL/SQL変数へのCLOB
列の選択
CLOB
変数へのVARCHAR2
列の選択
CLOB
とVARCHAR2
間の割当ておよびパラメータの受渡し
PL/SQLにおけるVARCHAR2としてのCLOBへのアクセス
次の例は、CLOB
がVARCHAR2
として処理された場合のCLOB
データへのアクセス方法を示しています。
declare myStoryBuf VARCHAR2(4001); BEGIN SELECT ad_sourcetext INTO myStoryBuf FROM print_media WHERE ad_id = 12001; -- Display Story by printing myStoryBuf directly END; /
PL/SQLにおけるVARCHAR2へのCLOBの割当て
declare myLOB CLOB; BEGIN SELECT 'ABCDE' INTO myLOB FROM print_media WHERE ad_id = 11001; -- myLOB is a temporary LOB. -- Use myLOB as a lob locator DBMS_OUTPUT.PUT_LINE('Is temp? '||DBMS_LOB.ISTEMPORARY(myLOB)); END; /
SQLおよびPL/SQLでは、LONG
からLOBへの移行時に、特定の明示的な変換ファンクションにより他のデータ型とCLOB
、NCLOB
およびBLOB
間のデータ型の変更が行われます。
TO_CLOB()
: VARCHAR2
、NVARCHAR2
またはNCLOB
からCLOB
への変換。
TO_NCLOB
: VARCHAR2
、NVARCHAR2
またはCLOB
からNCLOB
への変換。
TO_BLOB()
: RAW
からBLOB
への変換。
TO_CHAR()
: CLOB
からCHAR
型への変換。このファンクションを使用してキャラクタLOBをデータベース・キャラクタ・セットに変換すると、変換するLOB値がターゲットの型よりも大きい場合、エラーが戻されます。暗黙的な変換でも、LOBデータが適合しない場合はエラーが発生します。
TO_NCHAR()
はNCLOB
型をNCHAR
型に変換します。このファンクションを使用して文字LOBを各国語キャラクタ・セットに変換する際、変換するLOB値がターゲットのデータ型よりも大きいと、データベースからエラーが返されます。暗黙的な変換でも、LOBデータが適合しない場合はエラーが発生します。
CAST
は、いずれのLOBデータ型も直接はサポートしていません。CAST
を使用してCLOB
値を文字データ型に変換する場合、NCLOB
値を各国語キャラクタ・データ型に変換する場合、またはBLOB
値をRAW
データ型に変換する場合に、データベースが暗黙的にLOB値を文字データまたはRAWデータに変換し、結果の値を明示的にターゲットのデータ型にキャストします。結果の値がターゲットのデータ型よりも大きい場合、データベースからエラーが返されます。
TO_NUMBER()
などの他の明示的な変換ファンクションは、サポートされていません(表16-1を参照)。変換ファンクションの詳細は、「LONGからLOBへの表列の移行」を参照してください。
LOBは重複するLONG
バインドをサポートしていません。
CLOB
およびVARCHAR2
は、2つの個別の型です。
ただし、使用方法によってはCLOBをSQLおよびPL/SQL VARCHAR2
組込みファンクションに渡し、VARCHAR2
と同様に使用できます。または、変数をDBMS_LOB
APIに渡して、LOBロケータと同様に動作させることができます。次の、「PL/SQLのCLOB変数」の複合的な例を参照してください。
PL/SQL VARCHAR2
ファンクションおよび演算子は、CLOB
を引数またはオペランドとして取得できます。
VARCHAR2
変数のサイズが、CLOB
を戻すファンクションの結果、またはCLOB
列に対するSELECT
の結果を含むために十分大きくない場合はエラーが発生し、操作は実行されません。これは、VARCHAR2
セマンティクスと一貫性があります。
PL/SQLのCLOB変数
1 declare 2 myStory CLOB; 3 revisedStory CLOB; 4 myGist VARCHAR2(100); 5 revisedGist VARCHAR2(100); 6 BEGIN 7 -- select a CLOB column into a CLOB variable 8 SELECT Story INTO myStory FROM print_media WHERE product_id=10; 9 -- perform VARCHAR2 operations on a CLOB variable 10 revisedStory := UPPER(SUBSTR(myStory, 100, 1)); 11 -- revisedStory is a temporary LOB 12 -- Concat a VARCHAR2 at the end of a CLOB 13 revisedStory := revisedStory || myGist; 14 -- The following statement raises an error because myStory is 15 -- longer than 100 bytes 16 myGist := myStory; 17 END;
「PL/SQLのCLOB変数」の10行目で一時CLOB
が暗黙的に作成され、revisedStory
CLOB
ロケータによって指されていることに注意してください。現行のインタフェースでは、この行を次のように展開できます。
buffer VARCHAR2(32000) DBMS_LOB.CREATETEMPORARY(revisedStory); buffer := UPPER(DBMS_LOB.SUBSTR(myStory,100,1)); DBMS_LOB.WRITE(revisedStory,length(buffer),1, buffer);
13行目では、myGist
が一時LOBの終わりに追加されます。これは、次の文と同じ影響があります。
DBMS_LOB.WRITEAPPEND(revisedStory, myGist, length(myGist));
場合によっては、PL/SQL文で暗黙的に作成された一時LOBは、以前に定義したLOBロケータの表現を変更できます。次の例について考えてみます。
ロケータとデータのリンケージの変更
1 declare 2 myStory CLOB; 3 amt number:=100; 4 buffer VARCHAR2(100):='some data'; 5 BEGIN 6 -- select a CLOB column into a CLOB variable 7 SELECT Story INTO myStory FROM print_media WHERE product_id=10; 8 DBMS_LOB.WRITE(myStory, amt, 1, buf); 9 -- write to the persistent LOB in the table 10 11 myStory:= UPPER(SUBSTR(myStory, 100, 1)); 12 -- perform VARCHAR2 operations on a CLOB variable, temporary LOB created. 13 -- Changes are not reflected in the database table from this point on. 14 15 update print_media set Story = myStory WHERE product_id = 10; 16 -- an update is necessary to synchronize the data in the table. 17 END;
7行目以降、myStory
は、print_media
内の永続LOBを表します。
8行目のDBMS_LOB.WRITE()
コールは、データを直接表に書き込みます。
UPDATE
文は不要です。続いて11行目で一時LOBが作成されてmyStory
に割り当てられます。これは、myStory
はローカルのVARCHAR2
変数のように使用されているためです。LOBロケータmyStory
は現在、新しく作成された一時LOBを指しています。
したがって、myStory
への変更は、これ以降はデータベースに反映されません。変更をデータベース表へ伝播するには、UPDATE
文が必要になります。以前は、永続LOBにUPDATE
が必要なかったことに注意してください。
注意:
SQL文によりLOBが戻される場合、またはLOBがPL/SQLファンクションまたはプロシージャのOUT
パラメータである場合は、一時LOBであるかどうかテストし、一時LOBである場合には操作完了後に解放する必要があります。
一時LOBの自動的および手動による解放
SELECT
または割当ての結果としてプログラム・ブロックで作成された一時LOBは、PL/SQLブロック、ファンクションまたはプロシージャの終了時に自動的に解放されます。また、DBMS_LOB.CREATETEMPORARY
で作成された一時LOBを解放してシステム・リソースおよび一時表領域を再生する必要があります。このためには、CLOB
変数上のDBMS_LOB.FREETEMPORARY
をコールします。
declare Story1 CLOB; Story2 CLOB; StoryCombined CLOB; StoryLower CLOB; BEGIN SELECT Story INTO Story1 FROM print_media WHERE product_ID = 1; SELECT Story INTO Story2 FROM print_media WHERE product_ID = 2; StoryCombined := Story1 || Story2; -- StoryCombined is a temporary LOB -- Free the StoryCombined manually to free up space taken DBMS_LOB.FREETEMPORARY(StoryCombined); StoryLower := LOWER(Story1) || LOWER(Story2); END; -- At the end of block, StoryLower is freed.
ネストしたファンクションによって戻される最終値がLOBでないかぎり、リモート・サイトで実行され、リモートLOBとBFILE
を操作する、組込みおよびユーザー定義型PL/SQLファンクションを使用できます。
この例では、「LOBの例の表: PMスキーマのprint_media表」で説明されているprint_media
表を使用します
次に例を示します。
SELECT product_id FROM print_media@dbs2 WHERE foo@dbs2(ad_sourcetext, 'aa') > 0; -- foo is a user-define function returning a NUMBER DELETE FROM print_media@dbs2 WHERE DBMS_LOB.GETLENGTH@dbs2(ad_graphic) = 0;
SQLファンクションに適用される制限はここにも適用されます。
関連項目:
1つのdblink
内のファンクションは、他のdblink内のLOBデータを操作できません。たとえば、次の文はサポートされていません。
SELECT a.product_id FROM print_media@dbs1 a, print_media@dbs2 b WHERE CONTAINS@dbs1(b.ad_sourcetext, 'aa') > 0;
1つの問合せブロックに、異なるdblink
の表およびファンクションを含めることはできません。たとえば、次の文はサポートされていません。
SELECT a.product_id FROM print_media@dbs2 a, print_media@dbs3 b WHERE CONTAINS@dbs2(a.ad_sourcetext, 'aa') > 0 AND foo@dbs3(b.ad_sourcetext) > 0; -- foo is a user-defined function in dbs3
PL/SQLからのSQL文の発行以外、PL/SQL内からのリモートLOB操作の実行(DBMS_LOB
)はサポートされていません。