15.3 LONG列をLOBに移行する際のその他の考慮事項
この項では、LONG列をLOBに移行する際のその他の考慮事項について説明します。
- LONGからLOBへのアプリケーションの移行
PL/SQL、JDBCおよびOCI環境でLONG
データ型と連携するほとんどのAPIは、LOBデータ型と連携するように拡張されています。 - LOB移行の代替方法
LONG
データ型をLOBに移行する場合、オンライン再定義をお薦めします。ただし、移行中にアプリケーションをオンラインのままにしておくことが重要でない場合は、次のいずれかの方法を使用してLONG
データをLOBに移行することもできます。
親トピック: SecureFile LOBへの列の移行
15.3.1 LONGからLOBへのアプリケーションの移行
PL/SQL、JDBCおよびOCI環境でLONG
データ型に使用するほとんどのAPIは、LOBデータ型にも使用できるように拡張されています。
LONG
データ型からLOBデータ型に変換された列を含む表を使用するPL/SQL、JDBCおよびOCIアプリケーションでは、アプリケーションの変更が最小限ですみます。- LOBロケータを扱わずにアプリケーションでLOBデータ型を使用できます。
関連項目:
-
データ・インタフェースに含まれるJDBCおよびOCI APIの詳細は、LOB用のデータ・インタフェースを参照してください。
-
LOBデータ型に対してサポートされるSQL構文の詳細は、「SQLセマンティクスとLOB」を参照してください。
-
LOBデータ型に対してサポートされるPL/SQL構文の詳細は、「LOBに対するPL/SQLセマンティクス」を参照してください。
ノート:
様々な手法を使用して、次のいずれかを行うことができます。
-
LONG
型の列からCLOB
列またはNCLOB
列への変換 -
LONG
RAW
型の列からBLOB
型の列への変換
特に明記しないかぎり、この章のLONGからLOBへの変換に関する説明は、これら2つのデータ型変換に適用されます。
ただし、LONG
データ型とLOBデータ型には、アプリケーションの移行計画に影響したり、アプリケーションの変更を必要とする違いがあります。
utldtree.sqlを使用したアプリケーション・リライトの識別
表をLONG
からLOB列型に移行する場合、PL/SQLアプリケーションの特定の部分のリライトが必要になることがあります。これがどの部分であるかは、rdbms/admin/utldtree.sql
ユーティリティを使用して判断できます。
utldtree.sql
ユーティリティを使用すると、指定のオブジェクトに依存するすべてのオブジェクトを再帰的に参照できます。たとえば、LONG
列を含む表に依存するオブジェクトをすべて参照できます。参照できるのは、権限があるオブジェクトのみです。
utldtree.sql
の使用方法は、utldtree.sqlファイル内に記載されています。また、utldtree.sql
が必要となるのはPL/SQLの場合のみです。SQLおよびOCIの場合は、アプリケーションを変更する必要はありません。
SQLの相違
- 索引: LONGおよびLOBデータ型では、ドメイン索引およびファンクション索引のみがサポートされます。
LONG
列のドメイン索引は、LONG
列をLOB列に変換する前に削除する必要があります。この索引は、移行後に手動で再作成できます。LONG
列のファンクション索引は、変換処理中は使用できなくなり、変換後に再作成する必要があります。ファンクション索引付けを使用するアプリケーション・コードは、再構築後に変更しなくても機能します。変換後に索引を再作成するステップは、次のとおりです。- 次のように、元の表から索引を選択します。
SELECT index_name FROM user_indexes WHERE table_name='LONG_TAB';
ノート:
この問合せでは、表名を大文字で指定する必要があります。 - 選択した索引ごとに、次のコマンドを使用します。
ALTER INDEX <index> REBUILD
- 次のように、元の表から索引を選択します。
- 制約:
LONG
列で有効な制約は、NULL
およびNOT NULL
のみです。LONG
列のすべての制約は、新しいLOB列に対して保持されます。これらの列に対する制約、またはこの表の他の列やプロパティを変更するには、移行後にALTER TABLE
文を使用します。 - デフォルト値: デフォルト値を指定しない場合、
LONG
列のデフォルト値がLOB列のデフォルト値となります。 - トリガー: 表の既存のトリガーのほとんどは引き続き使用できます。ただし、
AFTER UPDATE OF
トリガーのUPDATE OF
リストには、LOB列を作成できません。たとえば、次のCREATE TRIGGER文は無効です。CREATE TABLE t(lobcol CLOB); CREATE TRIGGER trig AFTER UPDATE OF lobcol ON t ...;
LONG
列は、この種のトリガーに作成できます。そのため、LOBに移行する前に、LONG
列のAFTER UPDATE OF
トリガーを削除する必要があります。 - クラスタ化表: クラスタ化表には、LOB列は作成できませんが、
LONG
は作成できます。表がクラスタの一部である場合、LONG
列またはLONG RAW
列はLOB列に変更できません。
空のLOBとNULLまたは長さが0(ゼロ)のLONGの違い
LOB列には、空のLOBを保持できます。空のLOBとは、完全に初期化済でデータが移入されていないLOBロケータです。LONG
データ型ではロケータが使用されないため、LONG
データ型には空という概念が適用されません。
LOB列値とLONG
列値はどちらも、初期値としてNULL
または空の文字列リテラルが挿入された場合は、NULL
値を持ちます。そのため、LONG
列にNULL
または長さ0(ゼロ)の値を使用するアプリケーション・コードは、列をLOB型に変換した後も同様に動作します。
対照的に、空として初期化されたLOBは、次の例に示すようにNULL
以外の値を持ちます。
CREATE TABLE long_tab(id NUMBER, long_col LONG);
CREATE TABLE lob_tab(id NUMBER, lob_col CLOB);
REM A zero length string inserts a NULL into the LONG column:
INSERT INTO long_tab values(1, '');
REM A zero length string inserts a NULL into the LOB column:
INSERT INTO lob_tab values(1, '');
REM Inserting an empty LOB inserts a non-NULL value:
INSERT INTO lob_tab values(1, empty_clob());
DROP TABLE long_tab;
DROP TABLE lob_tab;
アンカー型でのオーバーロード
アンカー型を使用したアプリケーションでは、LOBへの変換中に、オーバーロードされた変数が別のターゲットに解決される場合があります。たとえば、p
プロシージャが指定1および2でオーバーロードされるとします。
procedure p(l long) is ...; -- (specification 1)
procedure p(c clob) is ...; -- (specification 2)
また、次のプロシージャ・コールが使用されるとします。
declare
var longtab.longcol%type;
BEGIN
...
p(var);
...
END;
LONG
列からLOB列に移行する前に、このコールにより指定1に解決されます。longtab
がLOB列に移行すると、このコールは指定2に解決されます。これは、指定1のパラメータの型がCHAR
、VARCHAR2
、RAW
、LONG
RAW
の場合も同じであることに注意してください。
表をLONG
列からLOB列に移行した後、アプリケーションを手動で検査し、オーバーロードされたプロシージャの変更が必要かどうかを判断する必要があります。
移行前にLOB引数を取るオーバーロードされたプロシージャが含まれていたアプリケーションは、正常に動作しなくなる場合があります。これには、LONG
のアンカー型を使用しないアプリケーションも含まれます。たとえば、p
プロシージャに対する次の指定(1および2)とプロシージャ・コールを考えてみます。
procedure p(n number) is ...; -- (1)
procedure p(c clob) is ...; -- (2)
p('123'); -- procedure call
移行前には、CHAR
からNUMBER
への変換のみが可能であったため、指定1が選択されていました。移行後では、両方の変換が可能なため、コールの解釈が不明確になり、オーバーロード・エラーが発生します。
LOBデータ型に対してサポートされない一部の暗黙的変換
PL/SQLでは、NUMBER
、DATE
、ROW_ID
、BINARY_INTEGER
およびPLS_INTEGER
データ型からLONG
への暗黙的な変換が許可されますが、これらのデータ型からLOBへの暗黙的な変換は許可されません。
アプリケーションでこの種の暗黙的な変換を使用する場合、文字データにはTO_CHAR
演算子、バイナリ・データにはTO_RAW
演算子を使用して、これらの型を明示的に変換する必要があります。たとえば、アプリケーションに次のような割当て操作があるとします。
number_var := long_var; -- The RHS is a LOB variable after converting.
この場合は、コードを次のように変更する必要があります。
number_var := TO_CHAR(long_var);
-- Assuming that long_var is of type CLOB after conversion
LOB型の場合、次の変換はサポートされません。
-
BLOB
からVARCHAR2
、CHAR
またはLONG
-
CLOB
からRAW
またはLONG
RAW
これは、暗黙的な変換が発生する操作すべてに適用されます。たとえば、アプリケーションに次のようなSELECT
文があるとします。
SELECT long_raw_column INTO my_varchar2 VARIABLE FROM my_table
この場合、表の変換後にlong_raw_column
がBLOB
になると、SELECT
文でエラーが生成されます。この変換を機能させるには、次のように、TO_RAW
演算子を使用してBLOB
をRAW
に明示的に変換する必要があります。
SELECT TO_RAW(long_raw_column) INTO my_varchar2 VARIABLE FROM my_table
CLOB
をRAW
変数に選択する場合、CLOB
をRAW
に割り当てる場合、およびBLOB
をVARCHAR2
に割り当てる場合も同様です。
親トピック: LONG列をLOBに移行する際のその他の考慮事項
15.3.2 LOB移行の代替方法
LONG
データ型をLOBに移行するには、オンライン再定義をお薦めします。ただし、移行中にアプリケーションをオンラインのままにしておくことが重要でない場合は、次のいずれかの方法を使用してLONG
データをLOBに移行することもできます。
ALTER TABLEを使用したLONG列からLOB列への変換
関連項目:
移行に関する考慮事項SQLのALTER
TABLE
文を使用すると、LONG
列からLOB列に変換できます。
そのためには、次の構文を使用します。
ALTER TABLE [<schema>.]<table_name>
MODIFY ( <long_column_name> { CLOB | BLOB | NCLOB }
[DEFAULT <default_value>]) [LOB_storage_clause];
たとえば、次のように作成された表があるとします。
CREATE TABLE Long_tab (id NUMBER, long_col LONG);
この例では、次のALTER
TABLE
文を使用して、Long_tab
表のlong_col
列をCLOB
データ型に変更できます。
ALTER TABLE Long_tab MODIFY ( long_col CLOB );
ノート:
ALTER
TABLE
文は、表の内容を新しい領域にコピーし、操作の終了時に古い領域を解放します。このため、必要な領域が一時的に2倍になります。
ALTER
TABLE
文を使用してLONG
列をLOB列に変換する場合、次のオプションのみが許可されていることに注意してください。
-
DEFAULT
オプション LOB列のデフォルト値を指定できます。 -
LOB_storage_clause
変換する列のLOB記憶特性を指定できます。この句は、MODIFY
句で指定できます。
LONG
列をLOB型の列に変換する場合、ALTER
TABLE
文の他のオプションは使用できません。
TO_LOB演算子を使用したLONGからLOB列へのコピー
CREATE
TABLE
AS
SELECT
文またはINSERT
AS
SELECT
文でTO_LOB
演算子を使用すると、LONG
列からCLOB
列またはNCLOB
列に、またはLONG
RAW
列からBLOB
列にデータをコピーできます。たとえば、LONG
列を含む表が次のように作成されているとします。
CREATE TABLE Long_tab (id NUMBER, long_col LONG);
次の文を使用すると、列をLOB列にコピーできます。
CREATE TABLE Lob_tab (id NUMBER, clob_col CLOB);
INSERT INTO Lob_tab SELECT id, TO_LOB(long_col) FROM long_tab;
COMMIT;
INSERT
文がエラーを戻す場合は(UNDO用の領域がなかった場合)、WHERE
句を使用してLONG
データを少しずつLOB列に移行できます。データが正確にコピーされていることを確認した後、元の表を削除し、次のどちらかの手順を使用して新しい表のビューまたはシノニムを作成できます。
DROP TABLE Long_tab;
CREATE VIEW Long_tab (id, long_col) AS SELECT * from Lob_tab;
または
DROP TABLE Long_tab;
CREATE SYNONYM Long_tab FOR Lob_tab;
この一連の操作は、Long_tab
表のLong_col
列のデータ型をLONG
からCLOB
に変更する操作と同じです。この方法を使用する場合は、新しい表の制約、トリガー、権限付与および索引を再作成する必要があります。
TO_LOB
演算子の使用には、次のような制限事項があることに注意してください。
-
TO_LOB
を使用してデータをLOB列にコピーできますが、オブジェクト型のLOB属性にはコピーできません。 -
TO_LOB
はリモート表に使用できません。たとえば、次の文は機能しません。INSERT INTO tb1@dblink (lob_col) SELECT TO_LOB(long_col) FROM tb2; INSERT INTO tb1 (lob_col) SELECT TO_LOB(long_col) FROM tb2@dblink; CREATE TABLE tb1 AS SELECT TO_LOB(long_col) FROM tb2@dblink;
-
索引構成表の作成時に、
CREATE
TABLE
AS
SELECT
文のTO_LOB
演算子を使用してLONG
列またはLONG
RAW
列をLOB列に変換することはできません。この制限事項を回避するには、索引構成表を作成してから、
TO_LOB
演算子を使用してLONG
列またはLONG
RAW
列のINSERT
AS
SELECT
を実行します。 -
どのPL/SQLブロックの中でも
TO_LOB
を使用できません。
親トピック: LONG列をLOBに移行する際のその他の考慮事項