DBMS_METADATA.GET_DDL在PROCEDURE中不起作用

时间:2019-10-10 13:23:05

标签: oracle plsql

我创建了一个脚本来从DEVBASE用户复制表:

DECLARE
  YTABLE_NAME   CONSTANT VARCHAR2 (50) := 'TABLE_NAME';
  YRECREATE     CONSTANT BOOLEAN       := FALSE;
--
  XCOMMAND               CLOB;

  FUNCTION TABLE_EXISTS (ZTABLE_NAME IN VARCHAR2)
    RETURN BOOLEAN IS
    XCOUNT   NUMBER;
  BEGIN
    SELECT COUNT (*)
      INTO XCOUNT
      FROM USER_TABLES A
     WHERE A.TABLE_NAME = ZTABLE_NAME;

    RETURN XCOUNT > 0;
  END;
BEGIN
  IF TABLE_EXISTS (YTABLE_NAME) THEN
    IF YRECREATE THEN
      EXECUTE IMMEDIATE 'DROP TABLE ' || YTABLE_NAME || ' CASCADE CONSTRAINTS';
    ELSE
      RAISE_APPLICATION_ERROR (-20000, 'TABLE ' || YTABLE_NAME || ' ALREADY EXISTS');
    END IF;
  END IF;

  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', FALSE);
  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', FALSE);
  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', FALSE);
  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'EMIT_SCHEMA', FALSE);
  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_CREATION', FALSE);
  DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', FALSE);
  XCOMMAND := DBMS_METADATA.GET_DDL ('TABLE', YTABLE_NAME, 'DEVUSER');

  EXECUTE IMMEDIATE XCOMMAND;
END;

它可以工作,但是如果我使用此代码创建过程,则会收到错误消息“ ORA-31603:在模式DEVUSER中找不到类型为TABLE的对象{table name}”。

CREATE OR REPLACE PROCEDURE COPY_TABLE (YTABLE_NAME IN VARCHAR2, YRECREATE IN BOOLEAN) IS
BEGIN
  -- exact same code
END;

为什么会发生?

1 个答案:

答案 0 :(得分:1)

Oracle Documentation指出:

  

在存储过程,函数和   定义者权限包,角色已禁用。   因此,这样的PL / SQL程序可以   仅获取其中对象的元数据   自己的模式。如果你想写一个   提取元数据的PL / SQL程序   用于不同架构中的对象   ,您必须   程序调用者权限。

为此,您必须在过程中添加authid