1

如果我执行以下操作,一切都很好:

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;
/

并通过“执行测试”执行程序;然后我捕获了一个在模式 SCOTT 中找不到的 USER 类型的对象 SCOTT。

为什么会这样,我该如何解决?

谢谢克里斯

4

1 回答 1

3

Oracle文档指出:

在存储过程、函数和定义者权限包中,角色(例如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
于 2010-12-13T20:22:48.397 回答