【问题标题】:Stored procedure not returning correct result存储过程未返回正确结果
【发布时间】:2011-10-13 13:49:54
【问题描述】:

我有一个这样的存储过程

CREATE OR REPLACE PROCEDURE schema_name.CHECKS
IS
   tbl_name        VARCHAR2 (50);
   constraint_nm   VARCHAR2 (100);
   CURSOR cur_constraint
   IS
      SELECT DISTINCT table_name, constraint_name
        FROM all_constraints
       WHERE     constraint_type = 'R'
             AND STATUS = 'ENABLED'
             AND R_OWNER = 'owner1'
             AND r_constraint_name = 'constraint1';
BEGIN
   DBMS_OUTPUT.put_line ('Constraint Name');
   OPEN cur_constraint;
   LOOP
      FETCH cur_constraint
      INTO tbl_name, constraint_nm;
      EXIT WHEN cur_constraint%NOTFOUND;
      DBMS_OUTPUT.put_line (constraint_nm||'~~'||tbl_name);
   END LOOP;
   close cur_constraint;
END CHECKS;

我通过

执行这个过程
set serveroutput on

BEGIN
   schema_name.CHECKS ();
END;

我得到的输出是

Procedure created.
Constraint Name
PL/SQL procedure successfully completed.

它不返回任何结果,但理想情况下它应该返回一行(用于定义游标的选择查询将返回一行)。

当我像这样将上述代码作为 PL/SQL 块执行时

DECLARE
   tbl_name        VARCHAR2 (50);
   constraint_nm   VARCHAR2 (100);
   CURSOR cur_constraint
   IS
      SELECT DISTINCT table_name, constraint_name
        FROM all_constraints
       WHERE     constraint_type = 'R'
             AND STATUS = 'ENABLED'
             AND R_OWNER = 'owner1'
             AND r_constraint_name = 'constraint1';
BEGIN
   FOR i IN cur_constraint
   LOOP
      EXIT WHEN cur_constraint%NOTFOUND;
      DBMS_OUTPUT.put_line (i.constraint_name||' is in '||i.table_name);
   END LOOP;
END;

它按预期返回一行。

请帮助我理解为什么除了我执行它的方式之外逻辑相同时它的行为很奇怪。

【问题讨论】:

    标签: oracle stored-procedures plsql


    【解决方案1】:

    我想这是因为您的架构只能通过角色访问某些“owner1”架构对象,而不是直接授予。存储过程不考虑角色。详情请见this AskTom thread

    正如 Gary Myers 所说,您可以将程序更改为:

    CREATE OR REPLACE PROCEDURE schema_name.CHECKS
    AUTHID CURRENT_USER
    IS
    ...
    

    然后它将显示运行它的用户可以看到的约束。

    【讨论】:

    • 我在一个名为“schema_name”的模式中编译这个存储过程。 “owner1”仅存在于从“all_constraints”表中获取数据的选择查询中。如果我从“owner1”模式对象中选择数据,我觉得你的回答是有效的。或者我是否需要为“all_constraints”表授予“schema_name”的选择访问权限?截至目前,“all_constraints”拥有对“PUBLIC”的“选择”访问权限。
    • 这与您访问 ALL_CONSTRAINTS 视图无关;是 ALL_CONSTRAINTS 视图只向您显示您有权访问的表的约束。
    【解决方案2】:

    ALL_CONSTRAINTS 有点像一面镜子。根据对该用户的授权,每个用户都会在其中看到不同的东西。当作为 DEFINE RIGHTS 存储过程执行时,它只显示过程所有者可以看到的内容,这是直接授予所有者(而不是通过角色)权限的结果。

    当作为匿名块执行时,它将显示正在运行的用户由于直接授予用户权限或通过当前活动角色授予的权限而可以看到的内容。

    调用者权限存储过程 (google AUTHID CURRENT_USER) 将显示调用用户在直接或通过当前活动角色授予用户时可以看到的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-06
      • 2012-01-09
      • 2020-05-03
      • 2021-03-22
      • 2015-06-03
      • 2013-06-21
      • 1970-01-01
      相关资源
      最近更新 更多