Help us understand the problem. What is going on with this article?

データベース間でファイルの転送を行う DBMS_FILE_TRANSTER パッケージを試す

More than 1 year has passed since last update.

データベース・サーバー間のファイル転送

データベース・サーバー間でファイルを転送したい場合が時々あります。Data Pump のダンプ・ファイルのコピーを行う場合などです。
scp コマンド等を使っても良いのですが、Oracle Database 10g 以降であれば、DBMS_FILE_TRANSFER パッケージを使うことで PL/SQL プログラム内からファイルの転送を行うことができます。
この方法を使うことで、オペレーティング・システムに対するファイル・アクセスが制限されているパブリック・クラウド内のマネージド・データベース間(Amazon RDSなど)でも、ファイルの転送を行うことができます。

DBMS_FILE_TRANSFER パッケージを使う場合、以下の条件でファイル転送を行うことができます。

  • ファイルのコピー元、コピー先のディレクトリには DIRECTORY オブジェクトを使う。
  • コピー先とコピー元は DATABASE LINK オブジェクトによる認証を行う。
  • コピー元ユーザーは、コピー元 DIRECTORY に対する READ 権限、コピー先ユーザー(DATABASE LINK接続ユーザー)は、コピー先 DIRECTORY に対する WRITE 権限が必要。
  • リモート・データベースに対するファイルの作成、リモート・データベースからのファイルのコピー、ローカル・データベース内のコピーができる。
  • ファイル名の大文字/小文字は変換されない

ただし、ファイルであれば何でもコピーできるわけではなく、以下の制約があります。

  • ファイルのサイズは 512 バイトの倍数であること
  • ファイルのサイズの上限は 2 TB 以下

DBMS_FILE_TRANSFER パッケージ

DBMS_FILE_TRANSFER パッケージには以下のプロシージャが定義されています。

  • COPY_FILE
    ローカル・データベース内のファイル・コピー

  • GET_FILE
    リモート・データベース上のファイルを、ローカル・データベースにコピーする

  • PUT_FILE
    ローカル・データベース上のファイルをリモート・データベースにコピーする

準備

ここでは PUT_FILE プロシージャを使って、ローカル・データベース(O12R2A)に接続して、ローカル・データベースから、リモート・データベース(O12R2B)に対してファイルを転送する処理を行います。
まず転送データを作成します。下記の例では Data Pump ユーティリティのダンプ・ファイル(scott.dmp)を作成しています。
DIRECTORYオブジェクトは、標準の DATA_PUMP_DIR を使います。

$ expdp userid=SYSTEM/password SCHEMAS=scott DIRECTORY=DATA_PUMP_DIR DUMPFILE=scott.dmp

Export: Release 12.2.0.1.0 - Production on 火 2月 5 12:37:18 2019

Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
"SYSTEM"."SYS_EXPORT_SCHEMA_01"を起動しています: userid=SYSTEM/******** SCHEMAS=scott DIRECTORY=DATA_PUMP_DIR DUMPFILE=scott.dmp
オブジェクト型SCHEMA_EXPORT/TABLE/TABLE_DATAの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/STATISTICS/MARKERの処理中です
オブジェクト型SCHEMA_EXPORT/USERの処理中です
オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です
オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です
オブジェクト型SCHEMA_EXPORT/SEQUENCE/SEQUENCEの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です
オブジェクト型SCHEMA_EXPORT/PROCEDURE/PROCEDUREの処理中です
オブジェクト型SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDUREの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/INDEXの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINTの処理中です
. . "SCOTT"."EMPLOYEES"                         114.2 MB 8000000行がエクスポートされました
マスター表"SYSTEM"."SYS_EXPORT_SCHEMA_01"は正常にロード/アンロードされました
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_01に設定されたダンプ・ファイルは次のとおりです:
  /u01/app/oracle/admin/O12R2A/dpdump/scott.dmp
ジョブ"SYSTEM"."SYS_EXPORT_SCHEMA_01"が火 2月 5 12:38:25 2019 elapsed 0 00:00:56で正常に完了しました

ファイルが作成されたことを確認します。

$ sqlplus / as sysdba

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
に接続されました。

SQL> SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='DATA_PUMP_DIR';

DIRECTORY_PATH
--------------------------------------------------------------------------------
/u01/app/oracle/admin/O12R2A/dpdump/

SQL> 
SQL> !ls -l /u01/app/oracle/admin/O12R2A/dpdump/
合計 117432
-rw-r----- 1 oracle oinstall       118 12月 21 10:53 dp.log
-rw-r--r-- 1 oracle asmadmin      2227  2月  5 12:38 export.log
-rw-r----- 1 oracle asmadmin 120242176  2月  5 12:38 scott.dmp

次にデータ転送用にリモート・データベースに接続する DATABASE LINK オブジェクトを作成します。

$ sqlplus / as sysdba

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
に接続されました。

SQL> CREATE PUBLIC DATABASE LINK REMOTE_DL1 CONNECT TO SYSTEM IDENTIFIED BY password USING 'O12R2B';

データベース・リンクが作成されました。

転送先データベースでも DIRECTORY オブジェクトが存在することを確認します。

SQL> SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='DATA_PUMP_DIR';

DIRECTORY_PATH
--------------------------------------------------------------------------------
/u01/app/oracle/admin/O12R2B/dpdump/

ファイル転送の実行

PUT_FILE プロシージャを実行します。以下のパラメーターを指定します。

パラメーター名 データ型 説明
SOURCE_DIRECTORY_OBJECT VARCHAR2 コピー元 DIRECTORY オブジェクト名
SOURCE_FILE_NAME VARCHAR2 コピー元ファイル名
DESTINATION_DIRECTORY_OBJECT VARCHAR2 コピー先DIRECTORY オブジェクト名
DESTINATION_FILE_NAME VARCHAR2 コピー先ファイル名
DESTINATION_DATABASE VARCHAR2 コピー先データベースに接続する DATABASE LINK 名
SQL> BEGIN
  2      DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3  END;
  4  /

PL/SQLプロシージャが正常に完了しました。

SQL>

転送先データベースで、ファイルが存在するか確認します。

SQL> SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='DATA_PUMP_DIR';

DIRECTORY_PATH
--------------------------------------------------------------------------------
/u01/app/oracle/admin/O12R2B/dpdump/

SQL> !ls -l /u01/app/oracle/admin/O12R2B/dpdump/
合計 117428
-rw-r----- 1 oracle asmadmin       118  2月  5 11:55 dp.log
-rw-r----- 1 oracle asmadmin 120242176  2月  5 12:41 scott_dst.dmp

エラー発生

 PUT_FILEプロシージャを実行する際に発生する可能性があるエラーをいくつか再現します。

TNS識別子が存在しない

tnsnames.ora ファイルに記述された接続子名を間違えた場合のエラー。

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL2');
  3  END;
  4  /
BEGIN
*
行1でエラーが発生しました。:
ORA-02019: 指定されたリモート・データベースは存在しません。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

転送元 DIRECTORY が存在しない場合

source_directory_object パラメーターに指定した DIRECTORY オブジェクトが存在しない場合のエラー

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR1', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3  END;
  4  /
BEGIN
*
行1でエラーが発生しました。:
ORA-06564: オブジェクトDATA_PUMP_DIR1は存在しません。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

転送先 DIRECTORY が存在しない場合

destination_directory_object パラメーターに指定した DIRECTORY オブジェクトが存在しない場合のエラー

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR2', 'scott_dst.dmp', 'REMOTE_DL1');
  3  END;
  4  /
BEGIN
*
行1でエラーが発生しました。:
ORA-06564: オブジェクトDATA_PUMP_DIR2は存在しません。 ORA-02063:
先行のエラー・メッセージを参照してくださいline(REMOTE_DL1)。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

転送元ファイルが存在しない場合

source_file_name パラメーターに指定されたファイルが存在しない場合のエラー。

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp2', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3  END;
  4  /
BEGIN
*
行1でエラーが発生しました。:
ORA-19505:
ファイル"/u01/app/oracle/admin/O12R2A/dpdump/scott.dmp2"の識別に失敗しました。 ORA-27037:
ファイル・ステータスを取得できません。 Linux-x86_64 Error:
2: No such file or directory
Additional information: 7
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

書込み先にファイルが存在する

転送先ディレクトリに既に同名のファイルが存在する場合のエラー

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3  END;
  4  /
BEGIN
*
行1でエラーが発生しました。:
ORA-19504:
ファイル"/u01/app/oracle/admin/O12R2B/dpdump/scott_dst.dmp"の作成に失敗しました
。
ORA-27038: 作成したファイルはすでに存在します Additional
information: 1
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(REMOTE_DL1)。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

転送先データベース・インスタンスが停止している

転送先データベース・インスタンスまたはリスナー等が停止している場合のエラー。

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3  END;
  4  /
BEGIN
*
行1でエラーが発生しました。:
ORA-03150: データベース・リンクの通信チャネルでend-of-fileが検出されました ORA-02063:
先行のエラー・メッセージを参照してくださいline(REMOTE_DL1)。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3* END;
SQL> /
BEGIN
*
行1でエラーが発生しました。:
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

SQL> BEGIN
  2  DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
  3* END;
SQL> /
BEGIN
*
行1でエラーが発生しました。:
ORA-12541: TNS: リスナーがありません ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした