既存のスキーマを別のスキーマにコピーするためにDBMS_DATAPUMP
を呼び出す(パッケージ内の)プロシージャを記述しようとしています。コードは無名ブロックから実行すると機能しますが、プロシージャから次のエラーが発生します。
[Error] Execution (1: 1): ORA-31626: job does not exist
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79
ORA-06512: at "SYS.DBMS_DATAPUMP", line 1137
ORA-06512: at "SYS.DBMS_DATAPUMP", line 5285
ORA-06512: at "UTILITY.MANAGE_SCHEMA", line 71
ORA-06512: at line 1
このエラーは、DBMS_DATAPUMP.OPEN
呼び出しから生成されています。これは匿名ブロックで機能するため、これは実際には権限の問題であると想定しています(つまり、ロールを介して付与された1つ以上の権限が必要です)。ただし、datapumpを使用するために必要な権限に関するドキュメントは見つかりません。
この問題は、次のようになります。そのスキーマ内のパッケージがDBMS_DATAPUMP
を呼び出せるようにするには、ユーザー/スキーマに明示的に付与する必要があるアクセス許可はどれですか。
パッケージの所有者には、IMP_FULL_DATABASE
とEXP_FULL_DATABASE
の両方の役割と、DBA
の役割があります。
プロシージャコードは次のとおりです。
PROCEDURE copy_schema (p_source_schema VARCHAR2,
p_target_schema VARCHAR2,
p_asynchronous BOOLEAN := FALSE,
p_link_name VARCHAR2 := 'prddb') IS
dph NUMBER;
v_source_schema VARCHAR2 (30)
:= UPPER (DBMS_ASSERT.simple_sql_name (p_source_schema));
v_target_schema VARCHAR2 (30)
:= UPPER (DBMS_ASSERT.simple_sql_name (p_target_schema));
v_link_name VARCHAR2 (30)
:= UPPER (DBMS_ASSERT.qualified_sql_name (p_link_name));
v_job_name VARCHAR2 (30) := UPPER ('IMPORT_' || p_target_schema);
v_state VARCHAR2 (30);
BEGIN
DBMS_OUTPUT.put_line (
'Starting copy: source_schema = '
|| v_source_schema
|| '; target_schema = '
|| v_target_schema
|| '; link_name = '
|| v_link_name
|| '; job_name = '
|| v_job_name);
dph :=
DBMS_DATAPUMP.open ('IMPORT',
'SCHEMA',
v_link_name,
v_job_name);
DBMS_OUTPUT.put_line ('dph = ' || dph);
DBMS_DATAPUMP.metadata_filter (dph,
'SCHEMA_LIST',
'''' || v_source_schema || '''');
DBMS_DATAPUMP.metadata_remap (dph,
'REMAP_SCHEMA',
v_source_schema,
v_target_schema);
DBMS_DATAPUMP.set_parameter (dph, 'TABLE_EXISTS_ACTION', 'REPLACE');
DBMS_DATAPUMP.create_job_view (dph, UPPER (v_job_name || '_vw'));
DBMS_DATAPUMP.start_job (dph);
IF NOT p_asynchronous THEN
DBMS_DATAPUMP.wait_for_job (dph, v_state);
END IF;
END copy_schema;
私は one solution を見つけて、datapumpを呼び出すプロシージャを作成しましたが、SYSTEM
スキーマにプロシージャを配置することで問題を解決しています。
短い回答:パッケージまたはストアドプロシージャ内からCREATE TABLE
を呼び出すには、DBMS_DATAPUMP
をオブジェクト所有者に明示的に付与する必要があります。
長い答え:
この質問を解決するために、データディクショナリに問い合わせて、IMP_FULL_DATABASE
およびEXP_FULL_DATABASE
ロール(およびこれら2つのロールに割り当てられたすべてのロール)によって付与されたすべてのオブジェクトおよびシステム権限を取得しました。すべての2683特権を明示的に付与しようとすると2566失敗しましたが、パッケージはDBMS_DATAPUMP
を正常に呼び出すことができました。
質問は次のようになりました。残りの117の特権のどれが実際にDBMS_DATAPUMP
に必要ですか?次に、残りの特権をグループ化し、一度に1つのグループを取り消しました(これは、最終的に必要になる関連するアクセス許可のグループであると想定していました)。ほとんどすべてのグループを実行した後、CREATE ANY
特権のセットのみが残りました。そのグループを取り消すと、パッケージが機能しなくなりました。次に、それらの各アクセス許可を付与し、各付与後にパッケージを呼び出しました。機能をパッケージに復元したのはついにCREATE ANY TABLE
でした。さらに少しいじってみると、CREATE TABLE
は実際にはパッケージ内からDBMS_DATAPUMP
を呼び出すのに十分であると判断しました。
CREATE TABLE
は、質問に示されている手順にある機能に対して許可する必要があると私が見つけた唯一の権限です。その他の手順/データポンプ設定では、追加の権限が必要になる場合があります。たとえば、dbms_datapump.create_job_view
にはCREATE VIEW
が必要です。その場合、権限がない場合のエラーメッセージは、より合理的にはORA-01031: insufficient privileges
です。
ロールを介して取得した特権は、ストアドプロシージャでは無効です。パッケージを作成するアカウントに必要な権限を付与する必要があります。