6 Oracle Data Pump APIの使用

データ移動の操作は、Oracle Data Pump PL/SQL APIのDBMS_DATAPUMPを使用することで自動化できます。

Oracle Data Pump APIのDBMS_DATAPUMPは、あるサイトのデータとメタデータのすべてまたは一部をOracle Database間で移動するために使用できる高速なメカニズムを提供します。Oracle Data Pumpエクスポート・ユーティリティとOracle Data Pumpインポート・ユーティリティは、Oracle Data Pump APIに基づいています。

『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』

6.1 Oracle Data Pumpのクライアント・インタフェースAPIの動作

クライアント・インタフェースで使用されている主な構造体はジョブ・ハンドルで、コール元に対しては整数として表示されます。

ハンドルは、DBMS_DATAPUMP.OPENまたはDBMS_DATAPUMP.ATTACHファンクションを使用して作成します。他のセッションをジョブに接続してその進捗状況を監視および制御できます。ハンドルはセッション固有です。同じジョブによって、セッションごとに異なるハンドルを作成できます。DBAとして、この機能には仕事を離れる前にジョブを開始し、自宅からジョブの進行状況を見ることができる利点があります。

6.2 DBMS_DATAPUMPジョブの状態

Oracle Data PumpのDBMS_DATAPUMPジョブの状態を使用して、データ移動ジョブが実行しているステージと、各ステージで使用可能なオプションを確認します。

ジョブ状態の定義

ジョブの各フェーズは、次に示すように1つの状態に関連付けられています。

  • 未定義 — ハンドル作成前

  • 定義中 — ハンドルの最初の作成時

  • 実行中DBMS_DATAPUMP.START_JOBプロシージャの実行時

  • 完了中 — ジョブがその作業を完了し、Oracle Data Pumpプロセスを終了中

  • 完了 — ジョブの完了時

  • 停止保留中 — 手順に従ったジョブの停止が要求された場合

  • 停止中 — ジョブの停止処理を実行中

  • アイドル — 停止しているジョブに接続するためにDBMS_DATAPUMP.ATTACHが実行されてから、そのジョブを再開するためのDBMS_DATAPUMP.START_JOBが実行されるまでの期間

  • 未実行 — 実行されていない(関連付けられたOracle Data Pumpプロセスが存在しない)ジョブに対してData Pump制御ジョブ表が存在する状態

使用上のノート

アイドル状態のジョブに対してDBMS_DATAPUMP.START_JOBを実行すると、そのジョブは実行中状態に戻ります。

すべてのユーザーがDBMS_DATAPUMP.DETACHを実行して定義中状態のジョブとの接続を解除すると、そのジョブはデータベースから完全に削除されます。

ジョブが予期せず終了した場合やジョブを実行しているインスタンスが停止された場合、実行中状態またはアイドル状態であったジョブは未実行状態になります。その後、ジョブを再起動できます。

Oracle Data Pump制御ジョブ・プロセスは、「定義」「アイドル」「実行中」「停止中」「停止保留中」および「完了」状態でアクティブです。また、一時的に停止および完了の状態でもアクティブになります。ジョブのData Pump制御表は、未定義状態を除いてすべての状態で存在します。子プロセスは、実行中状態と停止保留中状態でのみアクティブになります。また、インポート・ジョブのワーカー・プロセスは、一時的に定義中状態でもアクティブになります。

ジョブが実行中状態のときに接続解除しても、そのジョブは停止しません。いつでも実行中のジョブに再接続して、そのジョブに関する状態情報の取得を再開できます。

DBMS_DATAPUMP.DETACHプロシージャが実行されると、明示的な接続解除が発生します。また、Oracle Data Pump APIセッションが停止した場合、Oracle Data Pump APIがOracle Data Pumpジョブと通信できない場合、またはDBMS_DATAPUMP.STOP_JOBプロシージャが実行された場合は、暗黙的な接続解除が発生します。

未実行」状態は、Data Pump制御ジョブ表が実行中のジョブのコンテキスト外に存在することを示します。この状態は、ジョブを停止した(通常は後で再開する)場合や、ジョブが異常な方法で終了した場合に発生します。また、この状態は、ジョブの開始時とOracle Data Pump制御ジョブ表を削除するまでのジョブの終了時に発生するジョブ状態の移行中に一時的に確認されることがあります。未実行状態は、DBA_DATAPUMP_JOBSビューとUSER_DATAPUMP_JOBSビューにのみ表示されます。GET_STATUSプロシージャから返されることはありません。

次の表に、DBMS_DATAPUMPプロシージャを実行できる有効なジョブ状態を示します。この表に示す状態は、特に指定がないかぎり、エクスポートとインポートの両方で有効です。

表6-1 DBMS_DATAPUMPプロシージャを実行できる有効なジョブの状態

プロシージャ名 有効な状態 説明

ADD_FILE

定義中(エクスポート・ジョブとインポート・ジョブの両方で有効)

実行中およびアイドル(エクスポート・ジョブでダンプ・ファイルを指定する場合にのみ有効)

ダンプ・ファイル・セット、ログ・ファイルまたはSQLFILE出力用のファイルを指定します。

ATTACH

定義中実行中アイドル停止完了完了中未実行

ユーザー・セッションで、ジョブの監視または停止したジョブの再開を可能にします。ジョブのダンプ・ファイル・セットまたはData Pump制御ジョブ表が削除されている場合や、なんらかの方法で変更されている場合、接続操作は失敗します。

DATA_FILTER

定義中

ジョブが処理するデータを制限する。

DETACH

すべて

ユーザー・セッションをジョブから切断する。

GET_DUMPFILE_INFO

すべて

ダンプ・ファイルのヘッダー情報を取得する。

GET_STATUS

完了未実行停止および未定義を除くすべての状態

ジョブの状態を取得する。

LOG_ENTRY

定義中実行中アイドル、停止保留中完了処理中

ログ・ファイルにエントリを追加する。

METADATA_FILTER

定義中

ジョブが処理するメタデータを制限する。

METADATA_REMAP

定義中

ジョブが処理するメタデータを再マップする。

METADATA_TRANSFORM

定義中

ジョブが処理するメタデータを変更する。

OPEN

未定義

新しいジョブを作成する。

SET_PARALLEL

定義中、実行中、アイドル

ジョブの並列度を指定する。

SET_PARAMETER

定義中

ノート: ENCRYPTION_PASSWORDパラメータは、状態が定義中およびアイドルのときに入力できます。

ジョブのデフォルトの処理を変更する。

START_JOB

定義中アイドル

ジョブを開始または再開する。

STOP_JOB

定義中実行中アイドル、停止保留中

ジョブの停止を開始する。

WAIT_FOR_JOB

完了未実行停止および未定義を除くすべての状態

ジョブの終了を待機する。

6.3 Oracle Data Pump APIを使用する場合の基本ステップ

Oracle Data Pump APIを使用するには、DBMS_DATAPUMPパッケージで提供されるプロシージャを使用します。

次のステップでは、オプションのステップを実行できるOracle Data Pumpジョブの実行時点を含む、データ・ポンプAPIの使用に関連する基本的なアクティビティを示します。これらのステップは、通常アクティビティを実行する順序で表示されます。
  1. Oracle Data Pumpジョブとそのインフラストラクチャを作成するには、DBMS_DATAPUMP.OPENプロシージャを実行します。
    プロシージャを実行すると、Oracle Data Pumpジョブが開始されます。
  2. ジョブで使用するパラメータを定義します。
  3. ジョブを開始します。
  4. (オプション)ジョブを完了まで監視できます。
  5. (オプション)ジョブとの接続を切断し、後で再接続します。
  6. (オプション)ジョブを停止します。
  7. (オプション)ジョブを再開します。

6.4 Oracle Data Pump APIの使用例

Oracle Data Pump APIの使用を開始するには、Oracle Data Pumpのエクスポートおよびインポートでできることを示す例を確認します。

6.4.1 データベースでのOracle Data Pump API例の使用

これらのスクリプトをコピーして実行する場合は、スクリプトを実行する前に、データベースで設定タスクを完了する必要があります。

Oracle Data Pump APIの例は、PL/SQLスクリプトの形式です。これらのサンプル・スクリプトを独自のデータベースで実行するには、必要なディレクトリ・オブジェクト、権限、ロールおよび表示設定が構成されていることを確認する必要があります。

例6-1 ディレクトリ・オブジェクトの作成と読取りおよび書込みアクセスの許可

この例では、アクセス権のあるdmpdirという名前のディレクトリ・オブジェクトを作成し、userを自分のユーザー名に置き換えます。

SQL> CREATE DIRECTORY dmpdir AS '/rdbms/work';
SQL> GRANT READ, WRITE ON DIRECTORY dmpdir TO user;

例6-2 EXP_FULL_DATABASEロールおよびIMP_FULL_DATABASEロールを所有していることを確認します。

セキュリティ・ドメイン内でユーザー自身に割り当てられているすべてのロールのリストを表示するには、次の文を入力します。

SQL> SELECT * FROM SESSION_ROLES;

表示されたロールを確認します。EXP_FULL_DATABASEおよびIMP_FULL_DATABASEロールが割り当てられていない場合は、データベース管理者に問い合せてください。

例6-3 サーバー表示出力の有効化

出力を画面に表示するには、サーバー出力がオンになっていることを確認します。これを行うには、次のコマンドを入力します。

SQL> SET SERVEROUTPUT ON

サーバーの表示出力がオンになっていない場合は、画面に表示されません。例を実行するセッションと同じセッションで、表示出力をONに設定する必要があります。この設定は、SQL*Plusを終了すると失われるため、新しいセッションの開始時に再設定する必要があります。また、別のユーザー名を使用してデータベースに接続する場合は、そのユーザーのSERVEROUTPUTONにリセットする必要があります。

6.4.2 Oracle Data Pumpを使用した簡単なスキーマ・エクスポートの実行

Oracle Data Pumpジョブを作成、開始および監視してスキーマのエクスポートを実行する方法の例を参照してください。

次の例のPL/SQLスクリプトは、Oracle Data Pump APIを使用してHRスキーマのスキーマ・エクスポートを簡単に実行する方法を示しています。この例は、ジョブを作成、開始、および監視する方法を示しています。この例の詳細は、スクリプト内のコメントを参照してください。例を簡単にしておくために、APIのコールでの例外は検出されません。ただし、本番環境でエラーが発生した場合は、例外ハンドラを定義してGET_STATUSをコールし、エラー情報の詳細を取得することをお薦めします。

このスクリプトを使用するには、ユーザーSYSTEMとして接続します。

DECLARE
  ind NUMBER;              -- Loop index
  h1 NUMBER;               -- Data Pump job handle
  percent_done NUMBER;     -- Percentage of job complete
  job_state VARCHAR2(30);  -- To keep track of job state
  le ku$_LogEntry;         -- For WIP and error messages
  js ku$_JobStatus;        -- The job status from get_status
  jd ku$_JobDesc;          -- The job description from get_status
  sts ku$_Status;          -- The status object returned by get_status
BEGIN

-- Create a (user-named) Data Pump job to do a schema export.

  h1 := DBMS_DATAPUMP.OPEN('EXPORT','SCHEMA',NULL,'EXAMPLE1','LATEST');

-- Specify a single dump file for the job (using the handle just returned)
-- and a directory object, which must already be defined and accessible
-- to the user running this procedure.

  DBMS_DATAPUMP.ADD_FILE(h1,'example1.dmp','DMPDIR');

-- A metadata filter is used to specify the schema that will be exported.

  DBMS_DATAPUMP.METADATA_FILTER(h1,'SCHEMA_EXPR','IN (''HR'')');

-- Start the job. An exception will be generated if something is not set up
-- properly. 

  DBMS_DATAPUMP.START_JOB(h1);

-- The export job should now be running. In the following loop, the job
-- is monitored until it completes. In the meantime, progress information is
-- displayed.
 
  percent_done := 0;
  job_state := 'UNDEFINED';
  while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
    dbms_datapump.get_status(h1,
           dbms_datapump.ku$_status_job_error +
           dbms_datapump.ku$_status_job_status +
           dbms_datapump.ku$_status_wip,-1,job_state,sts);
    js := sts.job_status;

-- If the percentage done changed, display the new value.

    if js.percent_done != percent_done
    then
      dbms_output.put_line('*** Job percent done = ' ||
                           to_char(js.percent_done));
      percent_done := js.percent_done;
    end if;

-- If any work-in-progress (WIP) or error messages were received for the job,
-- display them.

   if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
    then
      le := sts.wip;
    else
      if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
      then
        le := sts.error;
      else
        le := null;
      end if;
    end if;
    if le is not null
    then
      ind := le.FIRST;
      while ind is not null loop
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      end loop;
    end if;
  end loop;

-- Indicate that the job finished and detach from it.

  dbms_output.put_line('Job has completed');
  dbms_output.put_line('Final job state = ' || job_state);
  dbms_datapump.detach(h1);
END;
/

6.4.3 Oracle Data Pumpを使用したオブジェクト・ストアへの表モード・エクスポートの実行

DBMS_DATAPUMP.ADD_FILEを使用して表モード・エクスポートを実行する方法の例を参照してください。

このPL/SQLスクリプトでは、Oracle Data Pump DBMS_DATAPUMP APIは、ADD_FILEコールを使用して表のエクスポートでオブジェクト・ストアURI、資格証明およびファイル・タイプを指定します。ジョブの作成、開始、監視の方法を示しています。この例の詳細は、スクリプト内のコメントを参照してください。例を簡単にしておくために、APIのコールでの例外は検出されません。ただし、本番環境でエラーが発生した場合は、例外ハンドラを定義してGET_STATUSをコールし、エラー情報の詳細を取得することをお薦めします。

ノート:

資格証明、オブジェクト・ストアおよびネットワークACLSの設定などはすべて適切であるとみなされるため、スクリプトには含まれていません。

オンプレミス・システムのエキスパートを実行するOracle Data Pumpスクリプトと比較して、コールのスクリプトの違いに注意してください:

dbms_datapump.add_file(hdl, dumpFile, credName, '3MB', dumpType, 1);

プロシージャ・パラメータfilename (dumpFile)にはオフジェクト・ストアURIが含まれ、directory (credName)には資格証明が含まれ、filetype (dumpType)には新しいfiletypeキーワードが含まれます

次のコールに注意してください。
DBMS_DATAPUMP.ADD_FILE ( handle IN NUMBER, filename IN VARCHAR2, 
directory IN VARCHAR2, filesize IN VARCHAR2 DEFAULT NULL, filetype IN NUMBER DEFAULT 
DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE, reusefile IN NUMBER DEFAULT NULL);

また、スクリプト内のオブジェクトストアの定義に注意してください。

dumpFile     VARCHAR2(1024)  := 'https://example.oraclecloud.com/test/den02ten_foo3b_split_%u.dat';
  dumpType     NUMBER          := dbms_datapump.ku$_file_type_uridump_file;

例6-4 オブジェクト・ストアへの表モード・エクスポート

この表モード・エクスポートの例では、オブジェクト・ストアの資格証明、ネットワークACL、データベース・アカウントおよびオブジェクト・ストア情報がすでに設定されていることを前提としています。

Rem
Rem
Rem tkdpose.sql
Rem
Rem    NAME
Rem      tkdpose.sql - <one-line expansion of the name>
Rem
Rem    DESCRIPTION
Rem      Performs a table mode export to the object store.
Rem
Rem    NOTES
Rem      Assumes that credentials, network ACLs, database account and
Rem      object-store information already been setup.
Rem

connect test/mypwd@CDB1_PDB1

SET SERVEROUTPUT ON
SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100

DECLARE
  hdl          NUMBER;         -- Datapump handle
  ind          NUMBER;         -- Loop index
  le           ku$_LogEntry;   -- For WIP and error messages
  js           ku$_JobStatus;  -- The job status from get_status
  jd           ku$_JobDesc;    -- The job description from get_status
  sts          ku$_Status;     -- The status object returned by get_status
  jobState     VARCHAR2(30);   -- To keep track of job state 
  dumpType     NUMBER          := dbms_datapump.ku$_file_type_uridump_file;
  dumpFile     VARCHAR2(1024)  := 'https://example.oraclecloud.com/test/den02ten_foo3b_split_%u.dat';
  dumpType     NUMBER          := dbms_datapump.ku$_file_type_uridump_file;
  credName     VARCHAR2(1024)  := 'BMCTEST';
  logFile      VARCHAR2(1024)  := 'tkopc_export3b_cdb2.log';
  logDir       VARCHAR2(9)     := 'WORK';
  logType      NUMBER          := dbms_datapump.ku$_file_type_log_file;

BEGIN

  --
  -- Open a schema-based export job and perform defining-phase initialization.
  --
  hdl := dbms_datapump.open('EXPORT', 'TABLE');
  dbms_datapump.set_parameter(hdl, 'COMPRESSION', 'ALL');
  dbms_datapump.set_parameter(hdl, 'CHECKSUM', 1);
  dbms_datapump.add_file(hdl, logfile, logdir, null, logType);
  dbms_datapump.add_file(hdl, dumpFile, credName, '3MB', dumpType, 1);
  dbms_datapump.data_filter(hdl, 'INCLUDE_ROWS', 1);
  dbms_datapump.metadata_filter(hdl, 'TABLE_FILTER', 'FOO', '');
  --
  -- Start the job.
  --
  dbms_datapump.start_job(hdl);

  --
  -- Now grab output from the job and write to standard out.
  --
  jobState := 'UNDEFINED';
  WHILE (jobState != 'COMPLETED') AND (jobState != 'STOPPED')
  LOOP
    dbms_datapump.get_status(hdl,
           dbms_datapump.ku$_status_job_error +
           dbms_datapump.ku$_status_job_status +
           dbms_datapump.ku$_status_wip, -1, jobState,sts);
    js := sts.job_status;

    --
    -- If we received any WIP or Error messages for the job, display them.
    --
    IF (BITAND(sts.mask,dbms_datapump.ku$_status_wip) != 0) THEN
      le := sts.wip;
    ELSE
      IF (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) THEN
        le := sts.error;
      ELSE
        le := NULL;
      END IF;
    END IF;

    IF le IS NOT NULL THEN
      ind := le.FIRST;
      WHILE ind IS NOT NULL LOOP
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      END LOOP;
    END IF;
  END LOOP;

  --
  -- Detach from job.
  --
  dbms_datapump.detach(hdl);

  --
  -- Any exceptions that propagated to this point will be captured.
  -- The details are retrieved from get_status and displayed.
  --
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        dbms_datapump.get_status(hdl, dbms_datapump.ku$_status_job_error, 0,
                                 jobState, sts);
        IF (BITAND(sts.mask,dbms_datapump.ku$_status_job_error) != 0) THEN
          le := sts.error;
          IF le IS NOT NULL THEN
            ind := le.FIRST;
            WHILE ind IS NOT NULL LOOP
              dbms_output.put_line(le(ind).LogText);
              ind := le.NEXT(ind);
            END LOOP;
          END IF;
        END IF;

      BEGIN
        dbms_datapump.stop_job (hdl, 1, 0, 0);
      EXCEPTION
        WHEN OTHERS THEN NULL;
      END;

      EXCEPTION
      WHEN OTHERS THEN
        dbms_output.put_line('Unexpected exception while in exception ' ||
                             'handler. sqlcode = ' || TO_CHAR(SQLCODE));
      END;
END;
/
EXIT;
 

ログには、次の情報が報告されます。

Starting "TEST"."SYS_EXPORT_TABLE_01":  
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "TEST"."FOO"                                147.8 KB   70000 rows
Master table "TEST"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
Generating checksums for dump file set
******************************************************************************
Dump file set for TEST.SYS_EXPORT_TABLE_01 is:
  https://example.oraclecloud.com/test/den02ten_foo3b_split_01.dat
Job "TEST"."SYS_EXPORT_TABLE_01" successfully completed at Sun Dec 13 22:22:30 2020 elapsed 0 00:00:22

6.4.4 ダンプ・ファイルのインポートおよびすべてのスキーマ・オブジェクトの再マップ

Oracle Data Pumpジョブを作成、開始および監視してダンプ・ファイルのインポートを実行する方法の例を参照してください。

この例のスクリプトは、Oracle Data Pump APIの例「Oracle Data Pumpを使用した簡単なスキーマ・エクスポートの実行」(hrスキーマのエクスポート)で作成されたダンプ・ファイルをインポートします。すべてのスキーマ・オブジェクトがhrスキーマからblakeスキーマに再マップされます。例を簡単にしておくために、APIのコールでの例外は検出されません。ただし、本番環境でエラーが発生した場合は、例外ハンドラを定義してGET_STATUSをコールし、エラー情報の詳細を取得することをお薦めします。

このスクリプトを使用するには、ユーザーSYSTEMとして接続します。

DECLARE
  ind NUMBER;              -- Loop index
  h1 NUMBER;               -- Data Pump job handle
  percent_done NUMBER;     -- Percentage of job complete
  job_state VARCHAR2(30);  -- To keep track of job state
  le ku$_LogEntry;         -- For WIP and error messages
  js ku$_JobStatus;        -- The job status from get_status
  jd ku$_JobDesc;          -- The job description from get_status
  sts ku$_Status;          -- The status object returned by get_status
BEGIN

-- Create a (user-named) Data Pump job to do a "full" import (everything
-- in the dump file without filtering).

  h1 := DBMS_DATAPUMP.OPEN('IMPORT','FULL',NULL,'EXAMPLE2');

-- Specify the single dump file for the job (using the handle just returned)
-- and directory object, which must already be defined and accessible
-- to the user running this procedure. This is the dump file created by
-- the export operation in the first example.

  DBMS_DATAPUMP.ADD_FILE(h1,'example1.dmp','DMPDIR');

-- A metadata remap will map all schema objects from HR to BLAKE.

  DBMS_DATAPUMP.METADATA_REMAP(h1,'REMAP_SCHEMA','HR','BLAKE');

-- If a table already exists in the destination schema, skip it (leave
-- the preexisting table alone). This is the default, but it does not hurt
-- to specify it explicitly.

  DBMS_DATAPUMP.SET_PARAMETER(h1,'TABLE_EXISTS_ACTION','SKIP');

-- Start the job. An exception is returned if something is not set up properly.

  DBMS_DATAPUMP.START_JOB(h1);

-- The import job should now be running. In the following loop, the job is 
-- monitored until it completes. In the meantime, progress information is 
-- displayed. Note: this is identical to the export example.
 
 percent_done := 0;
  job_state := 'UNDEFINED';
  while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
    dbms_datapump.get_status(h1,
           dbms_datapump.ku$_status_job_error +
           dbms_datapump.ku$_status_job_status +
           dbms_datapump.ku$_status_wip,-1,job_state,sts);
    js := sts.job_status;

-- If the percentage done changed, display the new value.

     if js.percent_done != percent_done
    then
      dbms_output.put_line('*** Job percent done = ' ||
                           to_char(js.percent_done));
      percent_done := js.percent_done;
    end if;

-- If any work-in-progress (WIP) or Error messages were received for the job,
-- display them.

       if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
    then
      le := sts.wip;
    else
      if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
      then
        le := sts.error;
      else
        le := null;
      end if;
    end if;
    if le is not null
    then
      ind := le.FIRST;
      while ind is not null loop
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      end loop;
    end if;
  end loop;

-- Indicate that the job finished and gracefully detach from it. 

  dbms_output.put_line('Job has completed');
  dbms_output.put_line('Final job state = ' || job_state);
  dbms_datapump.detach(h1);
END;
/

6.4.5 Oracle Data Pumpを使用したオブジェクト・ストアへの表のインポート

Oracle Data Pumpジョブを作成、開始および監視してオブジェクト・ストアから表をインポートする方法の例を参照してください。

このPL/SQLスクリプトでは、Oracle Data Pump DBMS_DATAPUMP APIは、ADD_FILEコールを使用して表のエクスポートでオブジェクト・ストアURI、資格証明およびファイル・タイプを指定します。ジョブの作成、開始、監視の方法を示しています。この例の詳細は、スクリプト内のコメントを参照してください。例を簡単にしておくために、APIのコールでの例外は検出されません。ただし、本番環境でエラーが発生した場合は、例外ハンドラを定義してGET_STATUSをコールし、エラー情報の詳細を取得することをお薦めします。

ノート:

資格証明、オブジェクト・ストアおよびネットワークACLSの設定などはすべて適切であるとみなされるため、スクリプトには含まれていません。

例6-5 オブジェクト・ストアへの表モード・インポート

この表モード・インポートの例では、オブジェクト・ストアの資格証明、ネットワークACL、データベース・アカウントおよびオブジェクト・ストア情報がすでに設定されていることを前提としています。


Rem    NAME
Rem      tkdposi.sql 
Rem
Rem    DESCRIPTION
Rem      Performs a table mode import from the object-store.
Rem

connect test/mypwd@CDB1_PDB1

SET SERVEROUTPUT ON
SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100

DECLARE
  hdl          NUMBER;         -- Datapump handle
  ind          NUMBER;         -- Loop index
  le           ku$_LogEntry;   -- For WIP and error messages
  js           ku$_JobStatus;  -- The job status from get_status
  jd           ku$_JobDesc;    -- The job description from get_status
  sts          ku$_Status;     -- The status object returned by get_status
  jobState     VARCHAR2(30);   -- To keep track of job state
  dumpFile     VARCHAR2(1024)  := 'https://example.oraclecloud.com/test/den02ten_foo3b_split_%u.dat';
  dumpType     NUMBER          := dbms_datapump.ku$_file_type_uridump_file;
  credName     VARCHAR2(1024)  := 'BMCTEST';
  logFile      VARCHAR2(1024)  := 'tkopc_import3b_cdb2.log';
  logDir       VARCHAR2(9)     := 'WORK';
  logType      NUMBER          := dbms_datapump.ku$_file_type_log_file;

BEGIN

  --
  -- Open a schema-based export job and perform defining-phase initialization.
  --
  hdl := dbms_datapump.open('IMPORT', 'TABLE', NULL, 'OSI');
  dbms_datapump.add_file(hdl, logfile, logdir, null, logType);
  dbms_datapump.add_file(hdl, dumpFile, credName, null, dumpType);
  dbms_datapump.metadata_filter(hdl, 'TABLE_FILTER', 'FOO', '');
  dbms_datapump.set_parameter(hdl, 'TABLE_EXISTS_ACTION', 'REPLACE');
  dbms_datapump.set_parameter(hdl, 'VERIFY_CHECKSUM', 1);

  --
  -- Start the job.
  --
  dbms_datapump.start_job(hdl);

  --
  -- Now grab output from the job and write to standard out.
  --
  jobState := 'UNDEFINED';
  WHILE (jobState != 'COMPLETED') AND (jobState != 'STOPPED')
  LOOP
    dbms_datapump.get_status(hdl,
           dbms_datapump.ku$_status_job_error +
           dbms_datapump.ku$_status_job_status +
           dbms_datapump.ku$_status_wip, -1, jobState,sts);
    js := sts.job_status;

    --
    -- If we received any WIP or Error messages for the job, display them.
    --
    IF (BITAND(sts.mask,dbms_datapump.ku$_status_wip) != 0) THEN
      le := sts.wip;
    ELSE
      IF (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) THEN
        le := sts.error;
      ELSE
        le := NULL;
      END IF;
    END IF;

    IF le IS NOT NULL THEN
      ind := le.FIRST;
      WHILE ind IS NOT NULL LOOP
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      END LOOP;
    END IF;
  END LOOP;

  --
  -- Detach from job.
  --
  dbms_datapump.detach(hdl);

  --
  -- Any exceptions that propagated to this point will be captured.
  -- The details are retrieved from get_status and displayed.
  --
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        dbms_datapump.get_status(hdl, dbms_datapump.ku$_status_job_error, 0,
                                 jobState, sts);
        IF (BITAND(sts.mask,dbms_datapump.ku$_status_job_error) != 0) THEN
          le := sts.error;
          IF le IS NOT NULL THEN
            ind := le.FIRST;
            WHILE ind IS NOT NULL LOOP
              dbms_output.put_line(le(ind).LogText);
              ind := le.NEXT(ind);
            END LOOP;
          END IF;
        END IF;

      BEGIN
        dbms_datapump.stop_job (hdl, 1, 0, 0);
      EXCEPTION
        WHEN OTHERS THEN NULL;
      END;

      EXCEPTION
      WHEN OTHERS THEN
        dbms_output.put_line('Unexpected exception while in exception ' ||
                             'handler. sqlcode = ' || TO_CHAR(SQLCODE));
      END;
END;
/
EXIT;
 

ログ・ファイルには、次の情報が報告されます。

Verifying dump file checksums
Master table "TEST"."OSI" successfully loaded/unloaded
Starting "TEST"."OSI":  
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "TEST"."FOO"                                147.8 KB   70000 rows
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
;;; Ext Tbl Query Coord.: worker id 1 for "SYS"."IMPDP_STATS"
;;; Ext Tbl Query Coord.: worker id 1 for "SYS"."IMPDP_STATS"
;;; Ext Tbl Shadow: worker id 1 for "SYS"."IMPDP_STATS"
Job "TEST"."OSI" successfully completed at Sun Dec 13 22:24:16 2020 elapsed 0 00:00:40

6.4.6 簡単なスキーマ・エクスポート実行中の例外処理機能の使用方法

Oracle Data Pumpジョブを作成、開始および監視してスキーマのエクスポートを実行する方法の例を参照してください。

この例のスクリプトでは、データ・ポンプAPIを使用した簡単なスキーマ・エクスポートを示します。「Oracle Data Pumpを使用した簡単なスキーマ・エクスポートの実行」の例の延長で、例外処理機能を使用してSUCCESS_WITH_INFOケースを捕捉する方法およびGET_STATUSプロシージャを使用したエラーの詳細を取得する方法を示します。DBMS_DATAPUMP.OPENまたはDBMS_DATAPUMP.ATTACHエラーの例外情報を取得する場合は、DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR情報マスクとNULLジョブ・ハンドルを使用してDBMS_DATAPUMP.GET_STATUSをコールし、エラー情報の詳細を取得します。

このスクリプトを使用するには、ユーザーSYSTEMとして接続します。

DECLARE
  ind NUMBER;              -- Loop index
  spos NUMBER;             -- String starting position
  slen NUMBER;             -- String length for output
  h1 NUMBER;               -- Data Pump job handle
  percent_done NUMBER;     -- Percentage of job complete
  job_state VARCHAR2(30);  -- To keep track of job state
  le ku$_LogEntry;         -- For WIP and error messages
  js ku$_JobStatus;        -- The job status from get_status
  jd ku$_JobDesc;          -- The job description from get_status
  sts ku$_Status;          -- The status object returned by get_status
BEGIN

-- Create a (user-named) Data Pump job to do a schema export.

  h1 := dbms_datapump.open('EXPORT','SCHEMA',NULL,'EXAMPLE3','LATEST');

-- Specify a single dump file for the job (using the handle just returned)
-- and a directory object, which must already be defined and accessible
-- to the user running this procedure.

  dbms_datapump.add_file(h1,'example3.dmp','DMPDIR');

-- A metadata filter is used to specify the schema that will be exported.

  dbms_datapump.metadata_filter(h1,'SCHEMA_EXPR','IN (''HR'')');

-- Start the job. An exception will be returned if something is not set up
-- properly.One possible exception that will be handled differently is the
-- success_with_info exception. success_with_info means the job started
-- successfully, but more information is available through get_status about
-- conditions around the start_job that the user might want to be aware of.

    begin
    dbms_datapump.start_job(h1);
    dbms_output.put_line('Data Pump job started successfully');
    exception
      when others then
        if sqlcode = dbms_datapump.success_with_info_num
        then
          dbms_output.put_line('Data Pump job started with info available:');
          dbms_datapump.get_status(h1,
                                   dbms_datapump.ku$_status_job_error,0,
                                   job_state,sts);
          if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
          then
            le := sts.error;
            if le is not null
            then
              ind := le.FIRST;
              while ind is not null loop
                dbms_output.put_line(le(ind).LogText);
                ind := le.NEXT(ind);
              end loop;
            end if;
          end if;
        else
          raise;
        end if;
  end;

-- The export job should now be running. In the following loop, 
-- the job is monitored until it completes. In the meantime, progress information -- is displayed.
 
 percent_done := 0;
  job_state := 'UNDEFINED';
  while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
    dbms_datapump.get_status(h1,
           dbms_datapump.ku$_status_job_error +
           dbms_datapump.ku$_status_job_status +
           dbms_datapump.ku$_status_wip,-1,job_state,sts);
    js := sts.job_status;

-- If the percentage done changed, display the new value.

     if js.percent_done != percent_done
    then
      dbms_output.put_line('*** Job percent done = ' ||
                           to_char(js.percent_done));
      percent_done := js.percent_done;
    end if;

-- Display any work-in-progress (WIP) or error messages that were received for
-- the job.

      if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
    then
      le := sts.wip;
    else
      if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
      then
        le := sts.error;
      else
        le := null;
      end if;
    end if;
    if le is not null
    then
      ind := le.FIRST;
      while ind is not null loop
        dbms_output.put_line(le(ind).LogText);
        ind := le.NEXT(ind);
      end loop;
    end if;
  end loop;

-- Indicate that the job finished and detach from it.

  dbms_output.put_line('Job has completed');
  dbms_output.put_line('Final job state = ' || job_state);
  dbms_datapump.detach(h1);

-- Any exceptions that propagated to this point will be captured. The
-- details will be retrieved from get_status and displayed.

  exception
    when others then
      dbms_output.put_line('Exception in Data Pump job');
      dbms_datapump.get_status(h1,dbms_datapump.ku$_status_job_error,0,
                               job_state,sts);
      if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
      then
        le := sts.error;
        if le is not null
        then
          ind := le.FIRST;
          while ind is not null loop
            spos := 1;
            slen := length(le(ind).LogText);
            if slen > 255
            then
              slen := 255;
            end if;
            while slen > 0 loop
              dbms_output.put_line(substr(le(ind).LogText,spos,slen));
              spos := spos + 255;
              slen := length(le(ind).LogText) + 1 - spos;
            end loop;
            ind := le.NEXT(ind);
          end loop;
        end if;
      end if;
END;
/

6.4.7 Oracle Data Pumpジョブのダンプ・ファイル情報の表示

データ・ポンプ・ジョブのコンテキスト外でデータ・ポンプのダンプ・ファイルに関する情報を表示する方法の例を参照してください。

この例のPL/SQLスクリプトは、Oracle Data Pump APIプロシージャDBMS_DATAPUMP.GET_DUMPFILE_INFOを使用して、ジョブの実行中だけでなく、任意の時点でデータ・ポンプのダンプ・ファイルに関する情報を表示する方法を示しています。この例では、「Oracle Data Pumpを使用した簡単なスキーマ・エクスポートの実行」のPL/SQLサンプル・スクリプトで作成されたexample1.dmpダンプ・ファイルに含まれる情報を表示します。

また、このPL/SQLスクリプトを使用して、オリジナルのエクスポート(expユーティリティ)およびORACLE_DATAPUMP外部表アクセス・ドライバで作成されたダンプ・ファイルの情報を表示することもできます。

このスクリプトを使用するには、ユーザーSYSTEMとして接続します。

SET VERIFY OFF
SET FEEDBACK OFF
 
DECLARE
  ind        NUMBER;
  fileType   NUMBER;
  value      VARCHAR2(2048);
  infoTab    KU$_DUMPFILE_INFO := KU$_DUMPFILE_INFO();
 
BEGIN
  --
  -- Get the information about the dump file into the infoTab.
  --
  BEGIN
    DBMS_DATAPUMP.GET_DUMPFILE_INFO('example1.dmp','DMPDIR',infoTab,fileType);
    DBMS_OUTPUT.PUT_LINE('---------------------------------------------');
    DBMS_OUTPUT.PUT_LINE('Information for file: example1.dmp');
 
    --
    -- Determine what type of file is being looked at.
    --
    CASE fileType
      WHEN 1 THEN
        DBMS_OUTPUT.PUT_LINE('example1.dmp is a Data Pump dump file');
      WHEN 2 THEN
        DBMS_OUTPUT.PUT_LINE('example1.dmp is an Original Export dump file');
      WHEN 3 THEN
        DBMS_OUTPUT.PUT_LINE('example1.dmp is an External Table dump file');
      ELSE
        DBMS_OUTPUT.PUT_LINE('example1.dmp is not a dump file');
        DBMS_OUTPUT.PUT_LINE('---------------------------------------------');
    END CASE;
 
  EXCEPTION
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('---------------------------------------------');
      DBMS_OUTPUT.PUT_LINE('Error retrieving information for file: ' ||
                           'example1.dmp');
      DBMS_OUTPUT.PUT_LINE(SQLERRM);
      DBMS_OUTPUT.PUT_LINE('---------------------------------------------');
      fileType := 0;
  END;
 
  --
  -- If a valid file type was returned, then loop through the infoTab and 
  -- display each item code and value returned.
  --
  IF fileType > 0
  THEN
    DBMS_OUTPUT.PUT_LINE('The information table has ' || 
                          TO_CHAR(infoTab.COUNT) || ' entries');
    DBMS_OUTPUT.PUT_LINE('---------------------------------------------');
 
    ind := infoTab.FIRST;
    WHILE ind IS NOT NULL
    LOOP
      --
      -- The following item codes return boolean values in the form
      -- of a '1' or a '0'. Display them as 'Yes' or 'No'.
      --
      value := NVL(infoTab(ind).value, 'NULL');
      IF infoTab(ind).item_code IN
         (DBMS_DATAPUMP.KU$_DFHDR_MASTER_PRESENT,
          DBMS_DATAPUMP.KU$_DFHDR_DIRPATH,
          DBMS_DATAPUMP.KU$_DFHDR_METADATA_COMPRESSED,
          DBMS_DATAPUMP.KU$_DFHDR_DATA_COMPRESSED,
          DBMS_DATAPUMP.KU$_DFHDR_METADATA_ENCRYPTED,
          DBMS_DATAPUMP.KU$_DFHDR_DATA_ENCRYPTED,
          DBMS_DATAPUMP.KU$_DFHDR_COLUMNS_ENCRYPTED)
      THEN
        CASE value
          WHEN '1' THEN value := 'Yes';
          WHEN '0' THEN value := 'No';
        END CASE;
      END IF;
 
      --
      -- Display each item code with an appropriate name followed by
      -- its value.
      --
      CASE infoTab(ind).item_code
        --
        -- The following item codes have been available since Oracle
        -- Database 10g, Release 10.2.
        --
        WHEN DBMS_DATAPUMP.KU$_DFHDR_FILE_VERSION   THEN
          DBMS_OUTPUT.PUT_LINE('Dump File Version:         ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_MASTER_PRESENT THEN
          DBMS_OUTPUT.PUT_LINE('Master Table Present:      ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_GUID THEN
          DBMS_OUTPUT.PUT_LINE('Job Guid:                  ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_FILE_NUMBER THEN
          DBMS_OUTPUT.PUT_LINE('Dump File Number:          ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_CHARSET_ID  THEN
          DBMS_OUTPUT.PUT_LINE('Character Set ID:          ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_CREATION_DATE THEN
          DBMS_OUTPUT.PUT_LINE('Creation Date:             ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_FLAGS THEN
          DBMS_OUTPUT.PUT_LINE('Internal Dump Flags:       ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_JOB_NAME THEN
          DBMS_OUTPUT.PUT_LINE('Job Name:                  ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_PLATFORM THEN
          DBMS_OUTPUT.PUT_LINE('Platform Name:             ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_INSTANCE THEN
          DBMS_OUTPUT.PUT_LINE('Instance Name:             ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_LANGUAGE THEN
          DBMS_OUTPUT.PUT_LINE('Language Name:             ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_BLOCKSIZE THEN
          DBMS_OUTPUT.PUT_LINE('Dump File Block Size:      ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_DIRPATH THEN
          DBMS_OUTPUT.PUT_LINE('Direct Path Mode:          ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_METADATA_COMPRESSED THEN
          DBMS_OUTPUT.PUT_LINE('Metadata Compressed:       ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_DB_VERSION THEN
          DBMS_OUTPUT.PUT_LINE('Database Version:          ' || value);
 
        --
        -- The following item codes were introduced in Oracle Database 11g
        -- Release 11.1
        --

        WHEN DBMS_DATAPUMP.KU$_DFHDR_MASTER_PIECE_COUNT THEN
          DBMS_OUTPUT.PUT_LINE('Master Table Piece Count:  ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_MASTER_PIECE_NUMBER THEN
          DBMS_OUTPUT.PUT_LINE('Master Table Piece Number: ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_DATA_COMPRESSED THEN
          DBMS_OUTPUT.PUT_LINE('Table Data Compressed:     ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_METADATA_ENCRYPTED THEN
          DBMS_OUTPUT.PUT_LINE('Metadata Encrypted:        ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_DATA_ENCRYPTED THEN
          DBMS_OUTPUT.PUT_LINE('Table Data Encrypted:      ' || value);
        WHEN DBMS_DATAPUMP.KU$_DFHDR_COLUMNS_ENCRYPTED THEN
          DBMS_OUTPUT.PUT_LINE('TDE Columns Encrypted:     ' || value);
 
        --
        -- For the DBMS_DATAPUMP.KU$_DFHDR_ENCRYPTION_MODE item code a
        -- numeric value is returned. So examine that numeric value
        -- and display an appropriate name value for it.
        --
        WHEN DBMS_DATAPUMP.KU$_DFHDR_ENCRYPTION_MODE THEN
          CASE TO_NUMBER(value)
            WHEN DBMS_DATAPUMP.KU$_DFHDR_ENCMODE_NONE THEN
              DBMS_OUTPUT.PUT_LINE('Encryption Mode:           None');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_ENCMODE_PASSWORD THEN
              DBMS_OUTPUT.PUT_LINE('Encryption Mode:           Password');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_ENCMODE_DUAL THEN
              DBMS_OUTPUT.PUT_LINE('Encryption Mode:           Dual');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_ENCMODE_TRANS THEN
              DBMS_OUTPUT.PUT_LINE('Encryption Mode:           Transparent');
          END CASE;
 
        --
        -- The following item codes were introduced in Oracle Database 12c
        -- Release 12.1
        --
 
        --
        -- For the DBMS_DATAPUMP.KU$_DFHDR_COMPRESSION_ALG item code a
        -- numeric value is returned. So examine that numeric value and
        -- display an appropriate name value for it.
        --
        WHEN DBMS_DATAPUMP.KU$_DFHDR_COMPRESSION_ALG THEN
          CASE TO_NUMBER(value)
            WHEN DBMS_DATAPUMP.KU$_DFHDR_CMPALG_NONE THEN
              DBMS_OUTPUT.PUT_LINE('Compression Algorithm:     None');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_CMPALG_BASIC THEN
              DBMS_OUTPUT.PUT_LINE('Compression Algorithm:     Basic');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_CMPALG_LOW THEN
              DBMS_OUTPUT.PUT_LINE('Compression Algorithm:     Low');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_CMPALG_MEDIUM THEN
              DBMS_OUTPUT.PUT_LINE('Compression Algorithm:     Medium');
            WHEN DBMS_DATAPUMP.KU$_DFHDR_CMPALG_HIGH THEN
              DBMS_OUTPUT.PUT_LINE('Compression Algorithm:     High');
          END CASE;
        ELSE NULL;  -- Ignore other, unrecognized dump file attributes.
      END CASE;
      ind := infoTab.NEXT(ind);
    END LOOP;
  END IF;
END;
/