Хранимая процедура не возвращает правильный результат - PullRequest
6 голосов
/ 26 июля 2011

У меня есть такая хранимая процедура

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;

Он возвращает одну строку, как ожидалось.

Пожалуйста, помогите мне понять, почемуведет себя странно, когда логика та же, за исключением того, как я ее выполняю.

Ответы [ 2 ]

8 голосов
/ 26 июля 2011

Я предполагаю, что это потому, что ваша схема имеет доступ к некоторым объектам схемы 'owner1' только через роль и не предоставляется напрямую.Роли не учитываются хранимыми процедурами.См. эту ветку AskTom для получения более подробной информации.

Как говорит Гэри Майерс, вы можете изменить процедуру на:

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

, и тогда она покажет ограничения, которые пользовательработает он может видеть.

3 голосов
/ 27 июля 2011

ALL_CONSTRAINTS немного похоже на зеркало.Каждый пользователь увидит что-то свое, основываясь на грантах для этого пользователя.При выполнении в виде хранимой процедуры DEFINE RIGHTS она показывает только то, что может видеть владелец процедуры в результате привилегий, предоставленных непосредственно владельцу (не через роль).

При выполнении в виде анонимного блока онапокажет то, что работает пользователь может видеть в результате привилегий, предоставленных пользователю непосредственно ИЛИ через активную в настоящее время роль.

Хранимая процедура вызывающего права (google AUTHID CURRENT_USER) покажет, что вызывающий пользователь видитрезультат предоставления пользователю прав или через активную в данный момент роль.

...