为什么这是匿名但不是在程序中?

时间:2010-12-13 20:09:21

标签: oracle plsql dbms-metadata

如果我这样做,一切都很好:

declare
  l_foo clob;
begin
select
regexp_replace(
  dbms_metadata.get_ddl('USER', 'SCOTT', null) ||
  dbms_metadata.GET_GRANTED_DDL ('SYSTEM_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('OBJECT_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('ROLE_GRANT', 'SCOTT')
,'"' || chr(10), '";' || chr(10)) 
into l_foo 
from dual;
end;
/

但是如果我把它包装在一个程序中:

create procedure tests is
  l_foo clob;
begin
select
regexp_replace(
  dbms_metadata.get_ddl('USER', 'SCOTT', null) ||
  dbms_metadata.GET_GRANTED_DDL ('SYSTEM_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('OBJECT_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('ROLE_GRANT', 'SCOTT')
,'"' || chr(10), '";' || chr(10)) 
into l_foo 
from dual;
end;
/

通过“exec tests;”执行程序然后我在模式SCOTT中找到了一个USER类型的对象SCOTT。

为什么会这样,我该如何到处走走?

由于 克里斯

1 个答案:

答案 0 :(得分:3)

Oracle Documentation声明:

  

在存储过程,函数和   定义者 - 权利包,角色(例如   如SELECT_CATALOG_ROLE)被禁用。   因此,这样的PL / SQL程序可以   仅获取其中对象的元数据   自己的架构。如果你想写一个   获取元数据的PL / SQL程序   对于不同架构中的对象   (基于调用者拥有的   SELECT_CATALOG_ROLE),你必须做   程序调用者权利。

为此,您必须将authid添加到您的程序中。

create procedure tests authid CURRENT_USER is
  l_foo clob;
begin
select
regexp_replace(
  dbms_metadata.get_ddl('USER', 'SCOTT', null) ||
  dbms_metadata.GET_GRANTED_DDL ('SYSTEM_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('OBJECT_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('ROLE_GRANT', 'SCOTT')
,'"' || chr(10), '";' || chr(10)) 
into l_foo 
from dual;
end;
/

SQL> EXEC tests 

PL/SQL procedure successfully completed