LONG 型や LONG RAW 型のデータを、11.2 から19c の DB へ移行することはできるの?
ORA-00997: illegal use of LONG datatype が発生してデータ移行ができないことがある
ネットワークを経由して LONG / RAW を移行しているときに ORA-00997 が発生している場合、回避策は以下の二つのどちらか。
- データポンプを利用しダンプファイルを生成してデータ移行
- TO_LOB 関数を使ってデータ型を変換してからデータ移行
コンテンツ
ORA-00997 とは?
DBリンクなどネットワーク経由で LONG RAW データを移行しようとするとLONGデータ型の不正使用が発生する。
例えば、DBリンクを使ってソース側(DBリンク元)からターゲット側(DBリンク先)へ INSERT INTO を使い LONG RAW を含む表を移行しようとすると ORA-00997 が発生する。
以下に実際に発生させてみた例を記載する。
ソース側(11g)
LONG RAW カラムを含む表を作成
SQL> conn scott/tiger
Connected.
SQL> create table long_test(c1 number(4), c2_long long raw);
Table created.
SQL> insert into long_test values(1,'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
1 row created.
SQL> select * from long_test;
C1 C
---------- -
1 0
ターゲット側(19c)
src という名前のDBリンクを使って、ソース側のデータにアクセスできることを確認
SQL> create database link src connect to scott identified by tiger using 'src';
Database link created.
SQL> select * from long_test@src;
C1 C
---------- -
1 0
新しいテーブルを作成し、INSERT SELECT をDBリンク経由で実行すると...
SQL> create table long_test_copy (c1 number(4), c2_long long raw);
Table created.
SQL> insert into long_test_copy select * from long_test@src;
insert into long_test_copy select * from long_test@src
*
ERROR at line 1:
ORA-00997: illegal use of LONG datatype
回避策1:DataPump
ソース側 (11g)
EXPDP でダンプファイルを生成する
SQL> host expdp scott/tiger directory=dumpdir tables=long_test;
Export: Release 11.2.0.4.0 - Production on Tue Jul 20 12:19:57 2021
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Starting "SCOTT"."SYS_EXPORT_TABLE_01": scott/******** directory=dumpdir tables=long_test
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 64 KB
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "SCOTT"."LONG_TEST" 5.468 KB 1 rows
Master table "SCOTT"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SCOTT.SYS_EXPORT_TABLE_01 is:
/u01/app/hellomyworld/dumpdir/expdat.dmp
Job "SCOTT"."SYS_EXPORT_TABLE_01" successfully completed at Tue Jul 20 12:20:03 2021 elapsed 0 00:00:05
100% 96KB 21.6MB/s 00:00
DataPump の詳しい手順についてはこちらの記事を参考にしてね
ダンプファイルをターゲット側に転送する
scp <ダンプファイル名> <ユーザー名>@<IPアドレス>:<転送先のパス>
[hellomyworld@myhost dumpdir]$ scp expdat.dmp oracle@XXX.XX.XXX.XXX:/u01/app/oracle/dumpdir
The authenticity of host 'XXX.XX.XXX.XXX (XXX.XX.XXX.XXX)' can't be established.
ECDSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ECDSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'XXX.XX.XXX.XXX' (ECDSA) to the list of known hosts.
oracle@XXX.XX.XXX.XXX's password:
expdat.dmp
ターゲット側 (19c)
IMPDP で転送されたダンプファイルを使って該当テーブルをインポート
SQL> conn testuser/test
Connected.
SQL> host impdp testuser/test directory=dumpdir dumpfile=expdat.dmp;
Import: Release 19.0.0.0.0 - Production on Tue Jul 20 11:32:55 2021
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Master table "TESTUSER"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "TESTUSER"."SYS_IMPORT_FULL_01": testuser/******** directory=dumpdir dumpfile=expdat.dmp
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "SCOTT"."LONG_TEST" 5.468 KB 1 rows
Job "TESTUSER"."SYS_IMPORT_FULL_01" successfully completed at Tue Jul 20 11:33:05 2021 elapsed 0 00:00:09
ちゃんとデータ移行されている
SQL> conn scott/tiger
Connected.
SQL> select * from long_test;
C1 C
---------- -
1 0
回避策2: TO_LOB 関数
CLOB を格納させる表を作っておいて、そこに LONG データを TO_LOB関数を使い INSERT INTO する
ソース側 (11g)
SQL> create table lob_test (c1 number(4), c2_lob clob);
Table created.
SQL> insert into lob_test select c1, to_lob(c2_long) from long_test;
commit;
SQL> select * From lob_test;
C1 C
---------- -
1 0
LOB データなのでDBリンクを使ってデータ移行ができるようになる
ターゲット側 (19c)
SQL> create table lob_test_2 (c1 number(4), c2_lob clob);
Table created.
SQL> insert into lob_test_2 select * from lob_test@src;
1 row created.
SQL> select * From lob_test_2;
C1 C
---------- -
1 0
Oracle 公式ドキュメントを見てみると、上位バージョンでは LONG / RAW ではなく、 LOB の使用を推奨していることがわかる。
LONGデータ型
LONG列を使用した表を作成しないでください。かわりに、LOB列(CLOB、NCLOBまたはBLOB)を使用してください。
LONG列は、下位互換性のためにサポートされています。LONG列には、2GB(231)から1を引いたバイト数までの可変長の文字列を格納できます。
LONG列には、多くの点でVARCHAR2列と同じ特長があります。LONG列を使用すると、長いテキスト文字列を格納できます。
LONG値の長さは、ご使用のコンピュータで利用できるメモリーによって制限される場合もあります。
LONGリテラルは、テキスト・リテラルの説明のような形式になります。既存のLONG列もLOB列に変換することをお薦めします。
LOB列は、LONG列ほど制限は多くありません。
LOB機能はリリースごとに拡張されていますが、LONG機能は最近のリリースでは変更されていません。
LONG列からLOB列への変換については、「ALTER TABLE」のmodify_col_properties句および「TO_LOB」を参照してください。
RAWデータ型とLONG RAWデータ型
RAWデータ型とLONG RAWデータ型には、異なるシステム間でデータを移動する際にOracle Databaseによって明示的に変換されないデータが格納されます。これらのデータ型は、2進データおよびバイト列のために用意されています。たとえば、LONG RAWは、図形、音声、文書、またはバイナリ・データの配列の格納に使用できますが、解析方法は用途によって異なります。
LONG RAW列をバイナリLOB(BLOB)へ変換することをお薦めします。
LOB列は、LONG列ほど制限は多くありません。詳細は、「TO_LOB」を参照してください。
https://docs.oracle.com/cd/F19136_01/sqlrf/Data-Types.html#GUID-F6309DF8-162F-48A4-9454-FEE59EC6644F
-
データ型
docs.oracle.com