8 LOBに対するPL/SQLセマンティクス

内容は次のとおりです。

PL/SQL文およびPL/SQL変数

PL/SQLでは、セマンティクスが変更されました。

注意:

特に指定のないかぎり、PL/SQLセマンティクス、CLOBおよびVARCHAR2に関するほとんどの説明は、BLOBおよびRAWにも該当します。説明では、BLOBおよびRAWについては特に記載しません。

PL/SQLセマンティクスのサポートは、この項で説明します。

CLOBとVARCHAR2の間の暗黙的な変換

PL/SQLでは、CLOBからVARCHAR2へおよびVARCHAR2からCLOBへの暗黙的なデータ型変換が可能です。

これらの変換により、アプリケーションで次の操作を実行できます。

  • VARCHAR2 PL/SQL変数へのCLOB列の選択

  • CLOB変数へのVARCHAR2列の選択

  • CLOBVARCHAR2間の割当ておよびパラメータの受渡し

PL/SQLにおけるVARCHAR2としてのCLOBへのアクセス

次の例は、CLOBVARCHAR2として処理された場合の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では、次の明示的な変換関数によって、他のデータ型とCLOBNCLOBおよびBLOBの間でデータ型が変換されます。

  • TO_CLOB(): VARCHAR2NVARCHAR2またはNCLOBからCLOBに変換します

  • TO_NCLOB: VARCHAR2NVARCHAR2またはCLOBからNCLOBに変換します

  • TO_BLOB(varchar|clob, destcsid,[mime_type]): オブジェクトを現在のキャラクタ・セットからdestcsid内の指定されたキャラクタ・セットに変換します。結果として作成されるオブジェクトはBLOBです。次に、この変換関数の様々な使用方法を示します。

    • TO_BLOB(character, destcsid)
    • TO_BLOB(character, destcsid, mime_type)
    • TO_BLOB(clob, destcsid)
    • TO_BLOB(clob, destcsid, mime_type)

    destcsidが0の場合は、データベース・キャラクタ・セットIDに変換します。パラメータmime_typeは、セキュア・ファイルLOB列に対するINSERT文およびUPDATE文にのみ適用できます。mime_typeSELECT文、一時LOBまたはBasicFile LOBで使用されている場合は、無視されます。

  • TO_BLOB(varchar): BLOBに変換する前に入力をRAWに変換します。つまり、TO_BLOB(HEXTORAW(varchar))TO_BLOB(varchar)は同じです。

    注意:

    TO_BLOB(clob)はサポートされていません。
  • TO_CHAR(): CLOBからCHAR型に変換します。このファンクションを使用してキャラクタLOBをデータベース・キャラクタ・セットに変換すると、変換するLOB値がターゲットの型よりも大きい場合、エラーが戻されます。暗黙的な変換でも、LOBデータが適合しない場合はエラーが発生します。

  • TO_NCHAR(): NCLOBNCHAR型に変換します。このファンクションを使用して文字LOBを各国語キャラクタ・セットに変換する際、変換するLOB値がターゲットのデータ型よりも大きいと、データベースからエラーが返されます。暗黙的な変換でも、LOBデータが適合しない場合はエラーが発生します。

  • CASTは、LOBデータ型のいずれも直接的にサポートしていません。CASTを使用してCLOB値を文字データ型に変換する場合、NCLOB値を各国語キャラクタ・データ型に変換する場合、またはBLOB値をRAWデータ型に変換する場合に、データベースが暗黙的にLOB値を文字データまたはRAWデータに変換し、結果の値を明示的にターゲットのデータ型にキャストします。結果値がターゲットの型より大きい場合、エラーが戻されます。

TO_NUMBER()などの他の明示的な変換ファンクションは、サポートされていません(表7-1を参照)。

注意:

LOBは重複するLONGバインドをサポートしていません。

関連項目:

変換ファンクションの詳細は、「LONGからLOBへの列の移行」を参照してください

PL/SQL組込みファンクションでのVARCHAR2およびCLOB

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およびBFILE用のPL/SQLファンクション

関連項目:

リモートのLOBおよびBFILEをサポートするPL/SQLファンクションについては、「リモートLOBおよびBFILE用のPL/SQLファンクション」を参照してください