为什么我的查询在程序(PL/SQL)中不返回记录,但在SQL中手动运行时却返回记录?
大家好,谢谢你们抽出时间来帮助我 我有以下疑问:为什么我的查询在程序(PL/SQL)中不返回记录,但在SQL中手动运行时却返回记录?,sql,oracle,plsql,Sql,Oracle,Plsql,大家好,谢谢你们抽出时间来帮助我 我有以下疑问: SELECT owner, object_name FROM all_objects WHERE owner IN ('EDI') ORDER BY object_type, object_name; 正如您在屏幕截图中看到的,它返回一些值 当我从程序内部调用查询时,它不会返回任何值(参见第二个屏幕截图) 用于说明这一点的测试代码是: CREATE OR REPLACE PROCEDURE my_test AS BEGIN
SELECT owner, object_name
FROM all_objects
WHERE owner IN ('EDI')
ORDER BY object_type, object_name;
正如您在屏幕截图中看到的,它返回一些值
当我从程序内部调用查询时,它不会返回任何值(参见第二个屏幕截图)
用于说明这一点的测试代码是:
CREATE OR REPLACE PROCEDURE my_test
AS
BEGIN
DBMS_OUTPUT.put_line('Pre-Loop');
FOR indx IN (SELECT owner, object_name
FROM all_objects
WHERE owner IN ('EDI')
ORDER BY object_type, object_name)
LOOP
DBMS_OUTPUT.put_line('Object: ' || indx.owner || '.' || indx.object_name);
END LOOP;
DBMS_OUTPUT.put_line('Post-Loop');
END;
/
BEGIN
my_test();
END;
/
EDI模式是全新的,因此我怀疑这是一个授权/特权问题,但我似乎无法找到我可能缺少的内容,以便使其正常工作。我已经试着以EDI用户和SYS的身份运行这个
在得到答案后进行编辑:
我在一篇评论中提到,要找到这个问题的官方答案的替代方案,并希望确保稍后阅读本文的任何人都能分享,以便他们能够权衡同样的决定
向预期运行代码的用户应用授权,如执行任何程序或选择任何表格,都会起作用,但我确信有理由不给予如此广泛的授权。这就是你现在拥有的-根本没有结果:
SQL> CREATE OR REPLACE PROCEDURE my_test
2 AS
3 BEGIN
4 DBMS_OUTPUT.put_line('Pre-Loop');
5
6 FOR indx IN (SELECT owner, object_name
7 FROM all_objects
8 WHERE owner IN ('SCOTT')
9 AND rownum < 5 -- you don't have that
10 ORDER BY object_type, object_name)
11 LOOP
12 DBMS_OUTPUT.put_line('Object: ' || indx.owner || '.' || indx.object_name);
13 END LOOP;
14
15 DBMS_OUTPUT.put_line('Post-Loop');
16 END;
17 /
Procedure created.
SQL> BEGIN
2 my_test();
3 END;
4 /
PL/SQL procedure successfully completed.
您的存储过程是定义者权限存储过程。这意味着它不能访问通过角色授予的特权,只能访问直接授予过程所有者的特权。另一方面,除了用户的直接授权外,Ad-hoc-SQL还以当前会话中启用的任何角色的权限运行。最有可能的是,过程的所有者可以通过角色而不是直接授权访问相关的表 您可以通过运行
set role none;
然后运行特设SQL语句。如果我的赌注是正确的,那么由于您已禁用了会话的所有角色,特设SQL现在将返回0行
根据您将对该过程执行的操作,您可以通过将其转换为调用者权限存储过程来解决问题
CREATE OR REPLACE PROCEDURE my_test
AUTHID CURRENT_USER
AS
这将导致过程以调用方会话的权限(包括通过角色授予的权限)而不是定义方的权限运行。假设您要调用该过程的所有用户都有权访问
EDI
表,这就足够了。嗨,Justin,这对我的测试起到了作用,我犯的错误是没有让人知道我的实际问题是存储在包中的过程。为了方便演示这个问题,我做了一个单独的过程,但是这个AUTHID CURRENT_USER语句似乎只能在顶层使用,所以我必须将它放在整个包中。我还不知道我对此有何感想。我对补助金和特权不是很精通。我确实找到了另一种方法,但我不确定我想用哪种方法。看来我得到了我需要的,只需要决定一个选项。@bunchesbunches-授予选择任何表
或执行任何过程
在任何类型的安全审计中都将是一个巨大的危险信号。如果在您的用例中使用invoker的权限是不合适的,那么直接授予过程所有者对EDI
模式表的访问权,而不是通过角色,将更有意义。
CREATE OR REPLACE PROCEDURE my_test
AUTHID CURRENT_USER
AS