7.3 SQLおよびPL/SQL組込み関数によって作成される一時LOB

SQLまたはPL/SQL組込み関数からLOBが返される場合、返される結果は一時LOBです。同様に、ユーザー定義のPL/SQL関数またはプロシージャから値またはOUTパラメータとして戻されるLOBは、一時LOBである可能性があります。

PL/SQLでは、一時LOBの存続期間は、一時LOBが格納されているローカルPL/SQLプログラム変数と同じです。後続のSQLまたはPL/SQLのVARCHAR2ファンクションまたは問合せに、PL/SQLのローカル変数として渡すことができます。一時LOBは、プログラム・ブロックの最後にスコープから抜け、LOBが解放されます。これらは、PL/SQLのVARCHAR2変数と同じセマンティクスです。ただし、随時DBMS_LOB.FREETEMPORARY()コールを使用して、ローカルの一時LOBが使用したリソースを解放できます。

ノート:

SQL関数またはPL/SQL関数が一時LOBを返す場合、またはLOBがPL/SQL関数またはプロシージャのOUTパラメータである場合は、終了後すぐに解放する必要があります。そうしないと、一時LOBの蓄積が発生し、システムの速度が大幅に低下する可能性があります。

次の例は、SQL組込み関数を使用した一時LOBの暗黙的な作成を示しています。

DECLARE
  vc1 VARCHAR2(32000);
  lb1 CLOB;
  lb2 CLOB;
BEGIN
  SELECT clobCol1 INTO vc1 FROM tab WHERE colID=1;
  -- lb1 is a temporary LOB
  SELECT clobCol2 || clobCol3 INTO lb1 FROM tab WHERE colID=2;

  lb2 := vc1|| lb1;
  -- lb2 is a still temporary LOB, so the persistent data in the database 
  -- is not modified. An update is necessary to modify the table data.
  UPDATE tab SET clobCol1 = lb2 WHERE colID = 1;
  
DBMS_LOB.FREETEMPORARY(lb2); -- Free up the space taken by lb2
<... some more queries ...>
END; -- at the end of the block, lb1 is automatically freed 

次に、PL/SQL組込み関数を使用した一時LOBの暗黙的な作成の別の例を示します。

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;
/

前述の例では、次の点に注意してください。

  • 行番号7では、一時CLOBが暗黙的に作成され、revisedStory CLOBロケータによって指定されます。
  • 13行目では、一時LOBの最後にmyGistが追加され、次のコード・スニペットと同じ結果が得られます。
    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;

前述の例では、myStoryprint_media表の永続LOB列を表します。DBMS_LOB.WRITEプロシージャは、コード内のUPDATE文を使用せずに、表にデータを直接書き込みます。

続いて11行目で一時LOBが作成されてmyStoryに割り当てられます。これは、myStoryはローカルのVARCHAR2変数のように使用されているためです。LOBロケータmyStoryは現在、新しく作成された一時LOBを指しています。

したがって、myStoryへの変更は、これ以降はデータベースに反映されません。変更をデータベース表に伝播するには、UPDATE文を使用する必要があります。以前の永続LOBでは、UPDATE文は必要ありません。

関連項目:

リモートのLOBおよびBFILEをサポートするPL/SQL関数については、SQLおよびPL/SQLでのリモートLOBの操作を参照してください