PL/SQL et Grant

Par défaut les procédures, fonctions et packages PL/SQL héritent des droits de leur propriétaire… Voici l’illustration assez surprenante de ce point ci-dessous (n’utilisez pas le compte system pour ce genre de choses bien sur…) :

SQL> create table gark(id number);

Table created

SQL> create or replace procedure hr.test is
2 gark number;
3 begin
4 select count(*) into gark from system.gark;
5 end;
6 /

Warning: Procedure created with compilation errors.

SQL> show errors
Errors for PROCEDURE HR.TEST:

LINE/COL ERROR
-------- --------------------------------------------------
4/4 PL/SQL: SQL Statement ignored
4/42 PL/SQL: ORA-00942: table or view does not exist

SQL> desc system.gark
Name Null? Type
----------------------------------------- -------- -------
ID NUMBER

En donnant les privileges, ça marche parfaitement.

SQL> grant select on system.gark to hr;

Grant succeeded.

SQL> grant select on system.gark to hr.test;

SQL> alter procedure hr.test compile;

Procedure altered.

Bon mais vous savez tout ça… et peut-être que vous vous dites que donner les droits d’exécution non pas au propriétaire mais a l’utilisateur qui exécute le script pouvait être une autre solution ? Et tout cas, c’est ce que je me suis dit et bien non :


SQL> create or replace procedure hr.test
2 authid current_user is
3 gark number;
4 begin
5 select count(*) into gark from system.gark;
6 end;
7 /

Warning: Procedure created with compilation errors.

SQL> show errors
Errors for PROCEDURE HR.TEST:
LINE/COL ERROR
-------- ---------------------------------------------------------
5/4 PL/SQL: SQL Statement ignored
5/42 PL/SQL: ORA-00942: table or view does not exist

Dans ce cas aussi les privilèges sont valides en fonction du propriétaire du schéma au moment de la compilation… Enfin j’ai rien trouvée pour forcer la compilation dans ce cas. Peut-être quelqu’un a-t-il une astuce ?

-GarK!

1 réflexion sur “PL/SQL et Grant”

  1. Salut Grégory,

    Le fonctionnement que tu décris correspond au fonctionnement attendu.

    Le grant SELECT sur system.gark doit être effectif au moment de la compilation sinon PAS DE COMPILATION POSSIBLE.

    Par contre, en utilisant le DYNAMIC SQL, tu peux compiler correctement ton programme (sous compte HR) :

    create or replace PROCEDURE TEST
    authid current_user
    AS
    v_count_tgark integer ;
    err_num NUMBER ;
    err_msg VARCHAR2(100) ;
    sql_stmt varchar2(255) default null;
    BEGIN
    sql_stmt := ‘select count(*) from system.gark’ ;
    execute immediate sql_stmt into v_count_tgark ;
    dbms_output.put_line(‘nombre de lignes dans system.gark :’||v_count_tgark);
    EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
    DBMS_OUTPUT.PUT_LINE(‘Pas de lignes dans system.gark !’);
    WHEN OTHERS THEN
    err_msg := SUBSTR(SQLERRM, 1, 100);
    DBMS_OUTPUT.PUT_LINE(err_msg);
    END TEST;

    puis faire :

    grant execute on test to system ;

    et tente ton execution sous system :
    set serveroutput on ;
    BEGIN
    HR.TEST () ;
    END;
    /

    Non, non, ne me dis pas merci…

Les commentaires sont fermés.