DataPump Oracle ORAエラー

ORA-00997: illegal use of LONG datatype が発生してデータ移行ができない原因と対処について

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

この記事が役に立ったという方は
ボタンをポチッとしてくれたら喜びます

-DataPump, Oracle, ORAエラー
-, ,