Il est probablement plus complexe que vous pensez même. L'instruction GRANT
est DDL, ce qui signifie qu'elle émet des validations implicites, ce qui signifie que vous ne pouvez pas la placer directement dans un trigger. Votre déclencheur doit soumettre un travail qui s'est déroulé dans une session distincte après que la transaction de déclenchement a été validée, ce qui ferait effectivement l'attribution. Et cela signifie que vous devez utiliser l'ancien package pour planifier le travail, car le DBMS_SCHEDULER
plus moderne commet implicitement.
Étant donné que vous ne devez pas créer de tables à la volée dans Oracle en premier lieu, l'emplacement approprié pour ce type de subvention est dans les scripts de construction que vous exécutez pour créer la table en premier lieu. S'appuyer sur des déclencheurs pour faire des choses comme des subventions a tendance à rendre plus difficile la réalisation de builds correctement car exécuter exactement le même script dans deux environnements différents peut générer deux résultats différents à cause des différences dans le trigger.
Si vous êtes déterminé à aller dans cette voie, cependant, vous voudrez probablement quelque chose comme
Une procédure qui accorde le privilège
CREATE OR REPLACE PROCEDURE grant_select_to_readrole(p_table_name IN VARCHAR2)
AS
BEGIN
EXECUTE IMMEDIATE 'grant select on ' || p_table_name || ' to readrole';
END;
Et un déclencheur qui soumet un travail qui appelle cette procédure
CREATE OR REPLACE TRIGGER osmm_grant_on_creation
AFTER CREATE ON OSMM.SCHEMA
AS
l_jobno PLS_INTEGER;
BEGIN
dbms_job.submit(l_jobno,
'BEGIN grant_select_to_readrole(''' || ora_dict_obj_name || '''); END;',
sysdate + interval '10' second);
END;
Si vous deviez essayer d'émettre dans le déclencheur DDL au niveau du schéma lui-même, vous obtiendrez une erreur
SQL> ed
Wrote file afiedt.buf
1 create or replace trigger after_create_on_scott
2 after create on schema
3 declare
4 begin
5 execute immediate 'grant select on scott.emp to hr';
6* end;
SQL>/
Trigger created.
SQL> create table foo(col1 number);
create table foo(col1 number)
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-30511: invalid DDL operation in system triggers
ORA-06512: at line 3
Des suggestions? Bien sûr: ne faites pas ça. Les autorisations accordées font partie de notre configuration de base de données. En tant que tels, ils doivent être scriptés et conservés dans un référentiel de contrôle de source, à côté du DDL pour créer la table. – APC
@APC - Pourquoi je ne voudrais pas faire ça?Je ne suis pas un administrateur de bases de données et j'ai une connaissance limitée d'Oracle. J'ai donc peur que votre réponse n'ait aucun sens. Existe-t-il un autre moyen d'accorder automatiquement des autorisations select à un rôle pour une nouvelle table? Parce que le faire manuellement est une corvée que nous aimerions éviter. Les déclencheurs semblaient être une solution évidente, mais s'il y a un «meilleur» moyen, je suis ouvert à cela. –
Les déclencheurs sont la seule façon d'accorder automatiquement des permissions sur des objets, à la demande, et ce n'est pas facile (comme le montre la réponse de Justin). C'est difficile car il est inhabituel de devoir accorder les mêmes autorisations sur toutes les tables d'un schéma à quelqu'un d'autre (rôle ou utilisateur). Il est plus commun d'accorder une variété de privilèges sur un sous-ensemble de tables, souvent à des comptes différents. C'est une logique difficile à mettre en place. L'approche la plus courante (autre que le codage cut'n'paste) consiste à utiliser des métadonnées pour générer des scripts. – APC