如何执行DBMS_METADATA.GET_DEPENDENT_DLL的IMMEDIATE输出?

时间:2015-01-23 20:55:55

标签: oracle plsql

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

要获得MYOBJECT的奖励,我会按照以下方式做点什么:

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;

返回类似于:

的内容
  

在“MYSCHEMA”上重新获得奖励。“MYOBJECT”到“SCHEMA1”并带有授权选项

     

授予执行“MYSCHEMA”。“MYOBJECT”至“SCHEMA2”并提供授权选项

     

在“MYSCHEMA”上获得FLASH FLACKBACK。“MYOBJECT”到“SCHEMA3”并带有授权选项

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

EXECUTE IMMEDIATE grants_obtained;

抛出:

  

ORA-00933:SQL命令未正确结束

有没有办法使用GET_DEPENDENT_DLL获取OBJECT的GRANTS并能够使用EXECUTE IMMEDIATE运行它们?

2 个答案:

答案 0 :(得分:2)

您需要告诉dbms_metadata生成终结符。这可以使用set_transform_param

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

所以你的PL / SQL Block变为:

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并将其拆分为单独的语句(对于“仅”授权,这可能不会那么难)
  2. 将输出假脱机到脚本中,然后从SQL * Plus中运行该脚本。

答案 1 :(得分:2)

变化:

EXECUTE IMMEDIATE grants_obtained;

要:

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

CREATE SCHEMA可以在授权之间运行多个授权语句而不使用终结符。