为什么这在匿名中有效,但在程序中无效?

发布于 2024-10-07 03:10:50 字数 909 浏览 9 评论 0原文

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

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测试;”执行该过程然后我捕获了在模式 SCOTT 中找不到的 USER 类型的对象 SCOTT。

这是为什么?我该如何解决?

谢谢 克里斯

If I do the following, everything is fine:

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

But if I wrap this in a procedure:

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

And execute the procedure by "exec tests;" then I catch a object SCOTT of type USER not found in schema SCOTT.

Why is this and how do I get around?

Thanks
Chris

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

百变从容 2024-10-14 03:10:50

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

Oracle Documentation states:

In stored procedures, functions, and
definers-rights packages, roles (such
as SELECT_CATALOG_ROLE) are disabled.
Therefore, such a PL/SQL program can
only fetch metadata for objects in its
own schema
. If you want to write a
PL/SQL program that fetches metadata
for objects in a different schema
(based on the invoker's possession of
SELECT_CATALOG_ROLE), you must make
the program invokers-rights.

To do this, you must add authid to your procedure.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文