从包内调用 DBMS_DATAPUMP 所需的权限

All*_*lan 4 oracle oracle-11g-r2 datapump

我正在尝试编写一个过程(在包内),该过程调用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
Run Code Online (Sandbox Code Playgroud)

此错误是从DBMS_DATAPUMP.OPEN调用中生成的。由于它在匿名块中工作,我假设这实际上是一个权限问题(即需要通过角色授予的一个或多个权限)。但是,我找不到有关使用数据泵所需的权限的任何文档。

这个问题归结为:需要明确授予用户/模式哪些权限才能使该模式中的包能够调用DBMS_DATAPUMP


包的主人既有IMP_FULL_DATABASEEXP_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;
Run Code Online (Sandbox Code Playgroud)

我找到了一种创建调用 datapump 过程的解决方案,但它通过将过程放入SYSTEM架构中来解决问题,我不想这样做。

All*_*lan 6

简短回答:CREATE TABLE必须明确授予对象所有者DBMS_DATAPUMP才能从包或存储过程中调用。


长答案:

为了解决这个问题,我查询了数据字典以获取IMP_FULL_DATABASEEXP_FULL_DATABASE角色授予的所有对象和系统权限(以及分配给这两个角色的所有角色)。尝试明确授予所有 2683 项权限导致 2566 次失败,但该程序包能够DBMS_DATAPUMP成功调用。

那么问题就变成了:剩下的 117 个特权中的哪一个是实际需要的DBMS_DATAPUMP?然后我将剩余的权限分组并一次撤销一组(我认为这是最终需要的一组相关权限)。在遍历了几乎所有的组之后,只剩CREATE ANY下一组特权。当我撤销该组时,程序包停止工作。然后我授予每个权限,在每次授予后调用包。终于CREATE ANY TABLE恢复了包的功能。进一步的修改确定,CREATE TABLE事实上,足以DBMS_DATAPUMP从包内调用。


CREATE TABLE是我发现需要为问题中显示的过程中找到的功能授予的唯一权限。其他程序/数据泵设置可能需要额外的权限。dbms_datapump.create_job_view,例如,需要CREATE VIEW。在这种情况下,权限丢失时的错误消息更合理的是ORA-01031: insufficient privileges