如何执行 DBMS_METADATA.GET_DEPENDENT_DLL 的立即输出?

How to EXECUTE IMMEDIATE output of DBMS_METADATA.GET_DEPENDENT_DLL?

我想通过 GET_DEPENDENT_DLL 获得一个对象的所有授权,删除该对象,然后能够使用 EXECUTE IMMEDIATE 再次授予它以前的所有权限。

为了获得 MYOBJECT 的 GRANTS,我做了一些事情:

DECLARE
    get_grants VARCHAR2(300) := 'SELECT DBMS_METADATA.GET_DEPENDENT_DDL (''OBJECT_GRANT'', :object_name, :owner) from dual';
    grants_obtained VARCHAR(30000);                                                   
BEGIN
    EXECUTE IMMEDIATE get_grants INTO grants_obtained USING 'MYOBJECT', 'MYSCHEMA';   
END;

这 returns 类似于:

GRANT QUERY REWRITE ON "MYSCHEMA"."MYOBJECT" TO "SCHEMA1" WITH GRANT OPTION

GRANT EXECUTE ON "MYSCHEMA"."MYOBJECT" TO "SCHEMA2" WITH GRANT OPTION

GRANT FLASHBACK ON "MYSCHEMA"."MYOBJECT" TO "SCHEMA3" WITH GRANT OPTION

结果的格式不是 EXECUTE IMMEDIATE 可以处理的方式。如果我尝试使用 EXECUTE IMMEDIATE 运行 它们失败:

EXECUTE IMMEDIATE grants_obtained;

投掷:

ORA-00933: SQL command not properly ended

有没有办法使用 GET_DEPENDENT_DLL 获得对象的 GRANTS 并能够 运行 使用 EXECUTE IMMEDIATE?

你需要告诉dbms_metadata生成一个终结符。这可以使用过程 set_transform_param

完成
dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM, 'SQLTERMINATOR', true);

所以你的 PL/SQL 块变成:

DECLARE
    get_grants VARCHAR2(300) := 'SELECT DBMS_METADATA.GET_DEPENDENT_DDL (''OBJECT_GRANT'', :object_name, :owner) from dual';
    grants_obtained CLOB;                                                   
BEGIN
    dbms_metadata.set_transform_param(dbms_metadata.SESSION_TRANSFORM, 'SQLTERMINATOR', true);
    EXECUTE IMMEDIATE get_grants INTO grants_obtained USING 'MYOBJECT', 'MYSCHEMA';   
END;
/

手册中有更多详细信息:https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_metada.htm#BGBJBFGE


编辑:

即使您配置 dbms_metadata 以添加 ;,您也不能 运行 使用 execute immediate 的那些语句。

execute immediate 一次只能 运行 一条语句。我只能想到您可以做的两件事:

  1. 解析返回的 SQL 并将其拆分为单独的语句(对于 "only" 授权,这可能并不难)
  2. 将输出假脱机到脚本中,然后从 SQL*Plus.
  3. 中 运行 该脚本

变化:

EXECUTE IMMEDIATE grants_obtained;

收件人:

EXECUTE IMMEDIATE 'create schema authorization MYSCHEMA '||grants_obtained;

CREATE SCHEMA 可以 运行 多个授权语句,授权之间没有终止符。