Почему это работает анонимно, а не в процедуре? - PullRequest
1 голос
/ 13 декабря 2010

Если я сделаю следующее, все в порядке:

declare
  l_foo clob;
begin
select
regexp_replace(
  dbms_metadata.get_ddl('USER', 'SCOTT', null) ||
  dbms_metadata.GET_GRANTED_DDL ('SYSTEM_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('OBJECT_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('ROLE_GRANT', 'SCOTT')
,'"' || chr(10), '";' || chr(10)) 
into l_foo 
from dual;
end;
/

Но если я заверну это в процедуре:

create procedure tests is
  l_foo clob;
begin
select
regexp_replace(
  dbms_metadata.get_ddl('USER', 'SCOTT', null) ||
  dbms_metadata.GET_GRANTED_DDL ('SYSTEM_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('OBJECT_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('ROLE_GRANT', 'SCOTT')
,'"' || chr(10), '";' || chr(10)) 
into l_foo 
from dual;
end;
/

И выполнить процедуру с помощью "exec tests;" затем я ловлю объект SCOTT типа USER, не найденный в схеме SCOTT.

Почему это так и как мне обойтись?

Спасибо Chris

1 Ответ

3 голосов
/ 13 декабря 2010

Oracle Документация Состояния:

В хранимых процедурах, функциях и пакеты определителей-прав, роли (такие как SELECT_CATALOG_ROLE) отключены. Следовательно, такая программа на PL / SQL может только получать метаданные для объектов в его собственная схема . Если вы хотите написать PL / SQL программа, которая выбирает метаданные для объектов в другой схеме (основанный на владении вызывающего SELECT_CATALOG_ROLE), вы должны сделать программа invokers-права.

Для этого необходимо добавить authid к вашей процедуре.

create procedure tests authid CURRENT_USER is
  l_foo clob;
begin
select
regexp_replace(
  dbms_metadata.get_ddl('USER', 'SCOTT', null) ||
  dbms_metadata.GET_GRANTED_DDL ('SYSTEM_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('OBJECT_GRANT', 'SCOTT') ||
  dbms_metadata.GET_GRANTED_DDL ('ROLE_GRANT', 'SCOTT')
,'"' || chr(10), '";' || chr(10)) 
into l_foo 
from dual;
end;
/

SQL> EXEC tests 

PL/SQL procedure successfully completed
...