首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我的查询在程序(PL/ SQL )中不返回记录,但是在SQL中手动运行时会返回记录?

为什么我的查询在程序(PL/ SQL )中不返回记录,但是在SQL中手动运行时会返回记录?
EN

Stack Overflow用户
提问于 2021-02-21 01:45:45
回答 2查看 79关注 0票数 1

大家好,谢谢你们抽出时间来帮助我。

我有以下查询:

代码语言:javascript
运行
复制
SELECT   owner, object_name
FROM     all_objects
WHERE    owner IN ('EDI')
ORDER BY object_type, object_name;

正如您在屏幕截图中看到的那样,它返回一些值。

当我从程序内部调用查询时,它不会返回任何值(参见第二个屏幕快照)。

说明这一点的测试代码是:

代码语言:javascript
运行
复制
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的身份运行这个程序。

得到答案后的编辑,

我在一条评论中提到要为这个问题找到正式答案的替代方案,并希望确保以后阅读这篇文章的任何人都能分享,这样他们就可以对这个决定进行同样的权衡。

向预期运行代码的用户应用EXECUTE ANY PROCEDURESELECT ANY TABLE这样的授权将有效,但我相信,有理由不提供如此广泛的开放授权。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-21 08:19:14

存储过程是定义者的权限存储过程。这意味着它不能访问通过角色授予的特权,而只能访问那些直接授予过程所有者的特权。另一方面,除了用户的直接授权之外,Ad还具有为当前会话启用的任何角色的特权。最有可能的是,程序所有者可以通过角色而不是通过直接授权访问有关表。

您可以通过运行

代码语言:javascript
运行
复制
set role none;

然后运行ad语句。如果我的押注是正确的,则由于禁用了会话的所有角色,特设SQL现在将返回0行。

取决于您将如何处理该过程,您可能能够通过将其转化为调用者权限存储过程来解决问题。

代码语言:javascript
运行
复制
CREATE OR REPLACE PROCEDURE my_test
  AUTHID CURRENT_USER
AS

这将导致过程以调用方会话的权限(包括通过角色授予的权限)而不是定义者的权限运行。假设您想要调用的所有用户都能够访问EDI表,那就足够了。

票数 1
EN

Stack Overflow用户

发布于 2021-02-21 07:30:31

这就是你现在所拥有的--根本没有结果:

代码语言:javascript
运行
复制
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.

但是,如果您启用了服务器输出,它就在这里!

代码语言:javascript
运行
复制
SQL> set serveroutput on                       --> this!
SQL>
SQL> BEGIN
  2      my_test();
  3  END;
  4  /
Pre-Loop
Object: SCOTT.BONUS
Object: SCOTT.DEPT
Object: SCOTT.EMP
Object: SCOTT.SALGRADE
Post-Loop

PL/SQL procedure successfully completed.

SQL>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66298364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档