¿Por qué funciona en anónimo pero no en un procedimiento?
-
09-10-2019 - |
Pregunta
Si hago lo siguiente, todo está bien:
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;
/
Pero si envuelvo esto en un procedimiento:
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;
/
Y ejecute el procedimiento mediante "pruebas ejecutivas"; Luego capto un objeto Scott de tipo usuario que no se encuentra en Schema Scott.
¿Por qué es esto y cómo me muevo?
Gracias Chris
Solución
Oráculo Documentación Estados:
En procedimientos almacenados, funciones y paquetes de derechos de definición, roles (como
SELECT_CATALOG_ROLE
) se desactivan. Por lo tanto, Tal programa PL/SQL solo puede obtener metadatos para objetos en su propio esquema. Si desea escribir un programa PL/SQL que obtenga metadatos para objetos en un esquema diferente (basado en la posesión del invocador deSELECT_CATALOG_ROLE
), debe hacer que el programa invoque a los derechos.
Para hacer esto, debes agregar authid
a su procedimiento.
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