2010-12-13 52 views
1

Si je fais ce qui suit, tout va bien:Pourquoi cela fonctionne dans l'anonymat mais pas dans une procédure?

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; 
/

Mais si je conclurai cela dans une procédure:

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; 
/

et exécuter la procédure par « essais exec; » alors j'attrape un objet SCOTT de type USER non trouvé dans le schéma SCOTT.

Pourquoi est-ce et comment je me déplace?

Merci Chris

Répondre

3

Oracle Documentation états:

Dans les procédures stockées, les fonctions et paquets Definers-droits, les rôles (tels que SELECT_CATALOG_ROLE) sont désactivées. Par conséquent, un tel programme PL/SQL peut récupèrent uniquement des métadonnées pour les objets dans son propre schéma . Si vous voulez écrire un programme PL/SQL qui va chercher les métadonnées des objets dans un autre schéma (basé sur la possession de l'invocateur de SELECT_CATALOG_ROLE), vous devez faire le programme invocateurs-droits.

Pour ce faire, vous devez ajouter authid à votre procédure.

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 
+0

aha, merci beaucoup! – chris