我有一个像这样的存储过程
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.
它没有返回任何结果,但理想情况下它应该返回一行(用于定义游标的select查询将返回一行)。
当我像上面这样的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;
按预期返回一行。
请帮助我理解为什么当逻辑相同时它会表现得很奇怪,除了我执行它的方式。
答案 0 :(得分:8)
我想这是因为您的架构只能通过角色访问某些“owner1”架构对象,而不是直接授予。存储过程不会考虑角色。有关详细信息,请参阅this AskTom thread。
正如Gary Myers所说,您可以将程序更改为:
CREATE OR REPLACE PROCEDURE schema_name.CHECKS
AUTHID CURRENT_USER
IS
...
然后它将显示运行它的用户可以看到的约束。
答案 1 :(得分:3)
ALL_CONSTRAINTS有点像镜子。根据对该用户的拨款,每个用户都会看到不同的内容。当作为DEFINE RIGHTS存储过程执行时,它仅显示过程的所有者可以看到由于直接授予所有者的权限(而不是通过角色)。
当作为匿名块执行时,它将显示正在运行的用户可以直接或通过当前活动的角色授予用户的权限。
调用者权限存储过程(google AUTHID CURRENT_USER)将显示调用用户可以直接或通过当前活动角色授予用户的内容。