7.1 LOBを使用した暗黙的な変換
この項では、PL/SQLでのLOB型から別のLOB型、またはLOB型から非LOB型への暗黙的な変換プロセスについて説明します。
次の各項の大部分では、print_media表を使用します。次に、print_media表の構造を示します。
図7-1 print_media表

- SQLでのCLOBデータ型とNCLOBデータ型の間の暗黙的な変換
この項では、CLOBデータ型とNCLOBデータ型の間の暗黙的な変換のサポートについて説明します。 - CLOBとVARCHAR2間の暗黙的な変換
この項では、CLOBデータ型とVARCHAR2データ型の間の暗黙的な変換のサポートについて説明します。 - BLOBとRAW間の暗黙的な変換
この項では、BLOBデータ型とRAWデータ型の間の暗黙的な変換のサポートについて説明します。 - LOBを使用した暗黙的な変換のガイドラインおよび制限事項
この項では、LOBのデータ・インタフェースを使用してLOB列またはLOB属性にアクセスする方法について説明します。 - LOBを使用した暗黙的な変換の詳細な例
この項の例では、INSERT操作およびUPDATE操作で複数のVARCHARおよびRAWバインドを使用する方法を示します。
親トピック: LOBに対するPL/SQLセマンティクス
7.1.1 SQLでのCLOBデータ型とNCLOBデータ型の間の暗黙的な変換
この項では、CLOBデータ型とNCLOBデータ型の間の暗黙的な変換のサポートについて説明します。
データベースでは、CLOBデータ型とNCLOBデータ型の間で、型間の割当てや型間でのパラメータの受渡しなどの操作を実行できます。これらの型間での暗黙的な変換は、文字セット・フォーマットなどのプロパティを保つために必要に応じて実行されます。
暗黙的な変換が発生すると、必要に応じて変換元LOBの各文字が変換先LOBの文字セットに変更されることに注意してください。この場合にデータのサイズが大きいと、パフォーマンスが低下する可能性があります。変換先と変換元の文字セットが同一であれば、パフォーマンスは低下しません。
CLOB型とNCLOB型の間で暗黙的な変換が発生した後、変換先LOBが一時LOBとして暗黙的に作成されます。この新しい一時LOBは、変換元LOBに依存しません。SELECT文で定義操作の一部として暗黙的な変換が発生する場合、次の例に示すように、変換先LOBの変更はそのLOBが選択された表内の永続LOBには影響しません。
SQL> -- check lob length before update
SQL> SELECT DBMS_LOB.GETLENGTH(ad_sourcetext) FROM Print_media
2 WHERE product_id=3106 AND ad_id = 13001;
DBMS_LOB.GETLENGTH(AD_SOURCETEXT)
---------------------------------
205
SQL>
SQL> DECLARE
2 clob1 CLOB;
3 amt NUMBER:=10;
4 BEGIN
5 -- select a clob column into a clob, no implicit convesion
6 SELECT ad_sourcetext INTO clob1 FROM Print_media
7 WHERE product_id=3106 and ad_id=13001 FOR UPDATE;
8 -- Trim the selected lob to 10 bytes
9 DBMS_LOB.TRIM(clob1, amt);
10 END;
11 /
PL/SQL procedure successfully completed.
SQL> -- Modification is performed on clob1 which points to the
SQL> -- clob column in the table
SQL> SELECT DBMS_LOB.GETLENGTH(ad_sourcetext) FROM Print_media
2 WHERE product_id=3106 AND ad_id = 13001;
DBMS_LOB.GETLENGTH(AD_SOURCETEXT)
---------------------------------
10
SQL>
SQL> ROLLBACK;
Rollback complete.
SQL> -- check lob length before update
SQL> SELECT DBMS_LOB.GETLENGTH(ad_sourcetext) FROM Print_media
2 WHERE product_id=3106 AND ad_id = 13001;
DBMS_LOB.GETLENGTH(AD_SOURCETEXT)
---------------------------------
205
SQL>
SQL> DECLARE
2 nclob1 NCLOB;
3 amt NUMBER:=10;
4 BEGIN
5
6 -- select a clob column into a nclob, implicit conversion occurs
7 SELECT ad_sourcetext INTO nclob1 FROM Print_media
8 WHERE product_id=3106 AND ad_id=13001 FOR UPDATE;
9
10 DBMS_LOB.TRIM(nclob1, amt); -- Trim the selected lob to 10 bytes
11 END;
12 /
PL/SQL procedure successfully completed.
SQL> -- Modification to nclob1 does not affect the clob in the table,
SQL> -- because nclob1 is a independent temporary LOB
SQL> SELECT DBMS_LOB.GETLENGTH(ad_sourcetext) FROM Print_media
2 WHERE product_id=3106 AND ad_id = 13001;
DBMS_LOB.GETLENGTH(AD_SOURCETEXT)
---------------------------------
205
関連項目:
すべてのデータ型に対してサポートされる暗黙的な変換の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。親トピック: LOBを使用した暗黙的な変換
7.1.2 CLOBとVARCHAR2の間の暗黙的な変換
この項では、CLOBデータ型とVARCHAR2データ型の間の暗黙的な変換のサポートについて説明します。
CLOBからVARCHAR2およびVARCHAR2からCLOBへの暗黙的なデータ型変換がサポートされています。
関連項目:
SQL文でのLOBサポートの詳細は、LOBのSQLセマンティクスを参照してください。ノート:
この項では、簡略化の例としてVARCHAR2データ型を使用していますが、CHARなどの他の文字型もCLOBによる暗黙的な変換に参加できます。
PL/SQLにおけるVARCHAR2へのCLOBの割当て
CLOBをVARCHAR2に割り当てると、CLOB列に格納されているデータが取り出され、VARCHAR2バッファに格納されます。バッファがすべてのCLOBデータを格納できるほど大きくない場合、切捨てエラーが発生し、データはバッファに書き込まれません。これは、VARCHAR2セマンティクスと一貫性があります。この割当て操作が正常に完了すると、VARCHAR2変数はデータを通常の文字バッファとして保持します。この操作は、次の方法で実行できます。
SELECT永続または一時CLOBデータをCHAR、VARCHAR2などの文字バッファ変数に格納します。単一のSELECT文では、このような定義を複数使用できます。CLOBをVARCHAR2またはCHAR変数に割り当てます。INSTR関数やSUBSTR関数など、VARCHAR2引数を受け入れる組込みSQL関数およびPL/SQL関数と演算子にCLOBデータ型を渡します。VARCHAR2データ型を受け入れるユーザー定義のPL/SQL関数にCLOBデータ型を渡します。
次の例は、CLOBがVARCHAR2として処理された場合のCLOBデータへのアクセス方法を示しています。
DECLARE
myStoryBuf VARCHAR2(32000);
myLob CLOB;
BEGIN
-- Select a LOB into a VARCHAR2 variable
SELECT ad_sourcetext INTO myStoryBuf FROM print_media WHERE ad_id = 12001;
DBMS_OUTPUT.PUT_LINE(myStoryBuf);
-- Assign a LOB to a VARCHAR2 variable
SELECT ad_sourcetext INTO myLob FROM print_media WHERE ad_id = 12001;
myStoryBuf := myLob;
DBMS_OUTPUT.PUT_LINE(myStoryBuf);
END;
/PL/SQLにおけるCLOBへのVARCHAR2の割当て
VARCHAR2をCLOBに割り当てられます。
VARCHAR2またはCHAR変数に格納されているINSERTまたはUPDATE文字データをCLOB列に格納します。このような複数のバインドは、単一のINSERT文またはUPDATE文で使用できます。VARCHAR2またはCHAR変数をCLOB変数に割り当てます。- LOBデータ型を受け入れるユーザー定義のPL/SQL関数に
VARCHAR2データ型を渡します。
DECLARE
myLOB CLOB;
BEGIN
-- Select a VARCHAR2 into a LOB variable
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));
-- Insert a VARCHAR2 into a lob column
INSERT INTO print_media(product_id, ad_id, AD_SOURCETEXT) VALUES (1000, 1, 'ABCDE');
-- Assign a VARCHAR2 to a LOB variable
myLob := 'XYZ';
END;
/親トピック: LOBを使用した暗黙的な変換
7.1.3 BLOBとRAWの間の暗黙的な変換
この項では、BLOBデータ型とRAWデータ型の間の暗黙的な変換のサポートについて説明します。
CLOBデータ型とVARCHAR2データ型の間の暗黙的な変換のPL/SQLセマンティクスに関連するほとんどの説明は、BLOBデータ型とRAWデータ型の間の暗黙的な変換プロセスにも適用されます。ただし、説明を簡潔にするために、この章のほとんどの例では、BLOBおよびRAWデータ型について明示的に説明していません。BLOBデータ型を含む次の操作では、暗黙的な変換がサポートされます。
RAW変数に格納されているINSERTまたはUPDATEバイナリ・データをBLOB列に格納します。このような複数のバインドは、単一のINSERT文またはUPDATE文で使用できます。SELECT永続または一時BLOBデータを、RAWなどのバイナリ・バッファ変数に格納します。このような複数の定義は、単一のSELECT文で使用できます。BLOBをRAW変数に割り当てるか、RAWをBLOB変数に割り当てます。RAWデータ型を受け入れるように定義された組込みまたはユーザー定義のPL/SQL関数にBLOBデータ型を渡すか、BLOBデータ型を受け入れるように定義された組込みまたはユーザー定義のPL/SQL関数にRAWデータ型を渡します。
親トピック: LOBを使用した暗黙的な変換
7.1.4 LOBを使用した暗黙的な変換のガイドラインおよび制限事項
この項では、LOBのデータ・インタフェースを使用してLOB列またはLOB属性にアクセスする方法について説明します。
CLOBおよびBLOB列または属性からのデータは、INSERT、UPDATE、SELECTなどの通常のSQL文によって参照できます。
PL/SQLには、ピース単位のINSERT、UPDATEまたはフェッチ用のルーチンがありません。したがって、LOB列またはLOB属性からアクセスできるデータ量は、PL/SQLの最大文字バッファ・サイズ(32767バイト)によって制限されます。このため、PL/SQLアプリケーションで永続LOB用のデータ・インタフェースを使用してアクセスできるLOBは、32KB未満に制限されます。
データ・インタフェースを使用して32KB -1バイトを超えるサイズのLOBにアクセスする必要がある場合、ピース単位の挿入およびフェッチにAPIを使用するには、PL/SQLコードからJDBCコールまたはOCIコールを実行する必要があります。
データ・インタフェースを使用してLOB列またはLOB属性にアクセスする場合は、次のガイドラインに従ってください。
-
SELECT操作PL/SQLでは、LOB列またはLOB属性を選択して文字バッファまたはバイナリ・バッファに格納できます。LOB列またはLOB属性がバッファ・サイズより大きい場合、データはバッファに格納されず、例外が発生します。LOB列またはLOB属性は、LOBロケータとしても選択できます。
-
INSERT操作
VALUES句の通常のINSERT文を使用して、LOB列またはLOB属性を含む表にINSERTできます。LOB列のフィールドは、リテラル、文字データ型、バイナリ・データ型またはLOBロケータです。 -
UPDATE操作LOB列またはLOB属性は、
UPDATE...SET文によって全体を更新できます。SET句では、新しい値にリテラル、文字データ型、バイナリ・データ型またはLOBロケータを使用できます。 -
4000バイトを超えるバインドには制限があります。
-
表に
LONG列とLOB列の両方がある場合、LONG列またはLOB列のいずれかに4000バイトを超えるデータをバインドできますが、同一の文で両方にバインドすることはできません。 -
INSERTASSELECT操作では、どのような長さのデータもLOB列にバインドできません。 - 4000バイトを超えるデータを
BLOBまたはCLOBにバインドし、そのデータがSQL演算子で構成される場合、結果のサイズは最大4000バイトに制限されます。たとえば、次の文は4000バイトのみ挿入します。LPADの結果は4000バイトに制限されるためです。INSERT INTO print_media (ad_sourcetext) VALUES (lpad('a', 5000, 'a')); -
サイズが4000バイトを超えるデータの場合、データベースでは16進から
RAWまたはRAWから16進への暗黙的な変換は実行されません。バッファのサイズが4000バイトを超える場合、文字データのバッファはバイナリ・データ型の列にバインドできず、バイナリ・データのバッファは文字データ型の列にバインドできません。この種のバインドを試みると、列データが4000バイトで切り捨てられます。たとえば、バッファのサイズが4000バイトを超える場合は、
VARCHAR2バッファをBLOB列にバインドできません。同様に、バッファのサイズが4000バイトを超える場合は、RAWバッファをCLOB列にバインドできません。
-
親トピック: LOBを使用した暗黙的な変換
7.1.5 LOBを使用した暗黙的な変換の詳細な例
この項の例では、INSERT操作およびUPDATE操作での複数のVARCHARおよびRAWバインドの使用方法を示します。
例7-1 INSERT操作およびUPDATE操作での文字およびRAWバインドの使用
次の例に、INSERT操作およびUPDATE操作でLOB列に文字およびRAWバインドを使用する方法を示します。
DECLARE
bigtext VARCHAR2(32767);
smalltext VARCHAR2(2000);
bigraw RAW (32767);
BEGIN
bigtext := LPAD('a', 32767, 'a');
smalltext := LPAD('a', 2000, 'a');
bigraw := utl_raw.cast_to_raw (bigtext);
/* Multiple long binds for LOB columns are allowed for INSERT: */
INSERT INTO print_media(product_id, ad_id, ad_sourcetext, ad_composite)
VALUES (2004, 1, bigtext, bigraw);
/* Single long bind for LOB columns is allowed for INSERT: */
INSERT INTO print_media (product_id, ad_id, ad_sourcetext)
VALUES (2005, 2, smalltext);
bigtext := LPAD('b', 32767, 'b');
smalltext := LPAD('b', 20, 'a');
bigraw := utl_raw.cast_to_raw (bigtext);
/* Multiple long binds for LOB columns are allowed for UPDATE: */
UPDATE print_media SET ad_sourcetext = bigtext, ad_composite = bigraw,
ad_finaltext = smalltext;
/* Single long bind for LOB columns is allowed for UPDATE: */
UPDATE print_media SET ad_sourcetext = smalltext, ad_finaltext = bigtext;
/* The following is NOT allowed because we are trying to insert more than
4000 bytes of data in a LONG and a LOB column: */
INSERT INTO print_media(product_id, ad_id, ad_sourcetext, press_release)
VALUES (2030, 3, bigtext, bigtext);
/* Insert of data into LOB attribute is allowed */
INSERT INTO print_media(product_id, ad_id, ad_header)
VALUES (2049, 4, adheader_typ(null, null, null, bigraw));
/* The following is not allowed because we try to perform INSERT AS
SELECT data INTO LOB */
INSERT INTO print_media(product_id, ad_id, ad_sourcetext)
SELECT 2056, 5, bigtext FROM dual;
END;
/
例7-2 SELECTにおけるLOBの複数の定義
次の例に、SQL問合せから複数の永続CLOBまたは一時CLOBを取り出してVARCHAR2変数に、またはBLOBをRAW変数に取得するSELECT操作の実行を示します。
DECLARE
ad_src_buffer VARCHAR2(32000);
ad_comp_buffer RAW(32000);
BEGIN
/* This retrieves the LOB columns if they are up to 32000 bytes,
* otherwise it raises an exception */
SELECT ad_sourcetext, ad_composite INTO ad_src_buffer, ad_comp_buffer FROM print_media
WHERE product_id=2004 AND ad_id=5;
/* This retrieves the temporary LOB produced by SUBSTR if it is up to 32000 bytes,
* otherwise it raises an exception */
SELECT substr(ad_sourcetext, 2) INTO ad_src_buffer FROM print_media
WHERE product_id=2004 AND ad_id=5;END;
/
例7-3 BLOBとRAWの間の暗黙的な変換
暗黙的な割当ては、次の例に示すように、明示的に宣言された変数と、%TYPE属性を使用して既存の列の型を参照することで宣言された変数に対して機能します。この例では、t表のlong_col列がLONGからCLOB列に移行されたものとします。
CREATE TABLE t (long_col LONG); -- Alter this table to change LONG column to LOB
DECLARE
a VARCHAR2(100);
b t.long_col%type; -- This variable changes from LONG to CLOB
BEGIN
SELECT * INTO b FROM t;
a := b; -- This changes from "VARCHAR2 := LONG to VARCHAR2 := CLOB
b := a; -- This changes from "LONG := VARCHAR2 to CLOB := VARCHAR2
END;
例7-4 PL/SQLからのPL/SQLプロシージャおよびCプロシージャのコール
PL/SQLまたはCのプロシージャをPL/SQLからコールできます。VARCHAR2が仮パラメータである実パラメータとしてCLOBを渡せ、CLOBが仮パラメータである実パラメータとしてVARCHAR2を渡せます。BLOBおよびRAWに対しても同様です。これにはどのような場合があるかというと、たとえば、仮パラメータまたは実パラメータがアンカー型の場合、つまり変数がtable_name.column_name%type構文を使用して宣言されている場合です。PL/SQLプロシージャまたはファンクションには、CLOBまたはVARCHAR2を仮パラメータとして指定できます。これは、組込みプロシージャおよびユーザー定義プロシージャと関数の両方に適用されます。
次の例は、プロシージャ・コール中の暗黙的な変換を示しています。
CREATE OR REPLACE PROCEDURE foo(vvv IN VARCHAR2, ccc INOUT CLOB) AS
...
BEGIN
...
END;
/
DECLARE
vvv VARCHAR2[32000] := rpad('varchar', 32000, 'varchar')
ccc CLOB := rpad('clob', 32000, 'clob')
BEGIN
foo(vvv, ccc); -- No implicit conversion needed here
foo(ccc, vvv); -- Implicit conversion for both parameters done here
END;
/
例7-5 PL/SQL組込み関数を使用した暗黙的変換
次の例では、PL/SQL組込み関数でのCLOBの使用方法を示します。
DECLARE
my_ad CLOB;
revised_ad CLOB;
myGist VARCHAR2(100):= 'This is my gist.';
revisedGist VARCHAR2(100);
BEGIN
INSERT INTO print_media (product_id, ad_id, ad_sourcetext)
VALUES (2004, 5, 'Source for advertisement 1');
-- select a CLOB column into a CLOB variable
SELECT ad_sourcetext INTO my_ad FROM print_media
WHERE product_id=2004 AND ad_id=5;
-- perform VARCHAR2 operations on a CLOB variable
revised_ad := UPPER(SUBSTR(my_ad, 1, 20));
-- revised_ad is a temporary LOB
-- Concat a VARCHAR2 at the end of a CLOB
revised_ad := revised_ad || myGist;
-- The following statement raises an error if my_ad is
-- longer than 100 bytes
myGist := my_ad;
END;
/
親トピック: LOBを使用した暗黙的な変換