IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

Erreur dans corps du trigger !


Sujet :

Oracle

  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 104
    Par défaut Erreur dans corps du trigger !
    bonjour,
    j'essaie de créer un utilisateur dans un trigger suite à une insertion dans une table.
    je récupère une erreur lors de l'insertion dans la table dû au trigger mais je ne vois pas c'est quoi au juste
    PS: l'utilisateur qui exécute ceci à le droit de créer des utilisateur!
    le voila mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    create or replace trigger a
    before insert on COMPTE
    for each row
    declare 
    begin
    EXECUTE IMMEDIATE 'CREATE USER '|| :new.nom_c||' IDENTIFIED BY '||:new.pwd_c 
    				|| 'Default tablespace ts_tables Quota 5M on ts_tables'
    				||' Temporary tablespace ts_temp  Quota 10M on ts_temp';
    EXECUTE IMMEDIATE 'grant create session to '|| :new.nom_c;
    end
    ;
    /
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    insert into compte values(3,'sara','sara','nulpart','sara@live.fr','sara',0,'p');
    l'erreure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ERREUR à la ligne 1 :
    ORA-04098: Déclencheur  'ADMIN_BIB.CONN_USER' non valide. Echec de la
    revalidation
    Merci de bien vouloire m'aider

  2. #2
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Quelle est la règle N°1 quand on code de l'execute immediate ?

    Réponse : Toujours AFFICHER la chaine exécutée et vérifier que la requête est correcte.

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 104
    Par défaut
    le fais dans les autres languages, pas encore de bonnes manières en pl/sql

    maintenant je l'ai essayé comme ceci ( j'espére ne pas avoir commis de bétises)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    set serveroutput on;
    create or replace trigger a
    before insert on COMPTE
    for each row
    declare 
    tst1 varchar2(400);
    tst2 varchar2(50);
    begin
    tst1 :='CREATE USER '|| :new.nom_c||' IDENTIFIED BY '||:new.pwd_c 
    				|| 'Default tablespace bib1_tables Quota 5M on bib1_tables'
    				|| ' Temporary tablespace bib_temp  Quota 10M on bib_temp';
    dbms_output.put_line(tst1);
    tst2 :='grant create session to '|| :new.nom_c;
    dbms_output.put_line(tst2);
    end
    ;
    /
    et ça retourne toujours la même erreure!

  4. #4
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Ça ne va pas aller: create user c’est du DDL et le DDL commit, ce qui n’est pas permis pour le trigger sauf s’il s’exécute dans une transaction autonome; mais ça montre souvent une incompréhension des triggers et transactions autonomes.
    Utilisez donc DBMS_JOB via le trigger pour créer votre utilisateur !

  5. #5
    Membre Expert Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Par défaut
    Il manque un espace devant 'default tablespace'

  6. #6
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Garuda Voir le message
    Il manque un espace devant 'default tablespace'
    Visiblement l'erreur est au niveau compil du trigger et pas de l'exécution (Déclencheur 'ADMIN_BIB.CONN_USER' non valide)
    Faire un show errors après la compil pour vérifier les erreurs.
    Chez moi il se compile bien (en mettant des valeurs de colonne des :new correspondant à ma table compte).

  7. #7
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 462
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Utilisez donc DBMS_JOB via le trigger pour créer votre utilisateur !
    Pour moi, avoir des opérations non transactionnelles ou asynchrones dans un déclencheur DML est une hérésie.
    Il me paraît nettement plus propre de créer une procédure creer_compte, qui se chargera de créer le compte si nécessaire, et de l'insérer dans la table.

  8. #8
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    Pour moi, avoir des opérations non transactionnelles ou asynchrones dans un déclencheur DML est une hérésie.
    Il me paraît nettement plus propre de créer une procédure creer_compte, qui se chargera de créer le compte si nécessaire, et de l'insérer dans la table.
    Ca reste toujours discutable. Je pense que le plus important est de bien comprendre qu’elles sont les implications. Ensuite le choix de la solution pourrait dépendre des autres contraintes.

  9. #9
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 104
    Par défaut
    excusez mes lacunes.
    Si j'ai bien compris je ne peut pas créer des utilisateurs via des triggers, je dois passer par un DBMS_JOB. mais d'après ce que j'ai lu DBMS_JOB c'est pour exécuter des requêtes chaque t moment alors que moi je veux le faire a chaque insertion dans la table compte.
    j'essaierais la proposition de Pomalaix de créer la procedure puis l'appeler dans le trigger

  10. #10
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 462
    Par défaut
    Citation Envoyé par nouraty Voir le message
    Si j'ai bien compris je ne peut pas créer des utilisateurs via des triggers, je dois passer par un DBMS_JOB. mais d'après ce que j'ai lu DBMS_JOB c'est pour exécuter des requêtes chaque t moment alors que moi je veux le faire a chaque insertion dans la table compte.
    j'essaierais la proposition de Pomalaix de créer la procedure puis l'appeler dans le trigger
    Vous pouvez techniquement tout à fait créer un utilisateur dans un déclencheur, mais comme disait Mnitu, ça nécessite que ce déclencheur soit défini en transaction autonome (car une opération DDL comme cette création d'utilisateur provoque un COMMIT implicite, ce qui est interdit dans un déclencheur ordinaire).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    connect system/system
    grant create user to system;
     
    create table compte(nom varchar2(30));
     
    create or replace trigger trig_compte
    before insert on compte
    for each row
    declare
    	pragma autonomous_transaction;
    begin
    	execute immediate 'create user ' || :new.nom || ' identified by ' || :new.nom;
    end;
    /
     
    insert into compte values('DEMO1');
    insert into compte values('DEMO2');
    Moi je ne suis pas partisan de cette méthode, et je préfère une procédure que vous appellerez à la place de l'INSERT.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    drop trigger trig_compte;
     
    create or replace procedure nouveau_compte(p_nom varchar2)
    is
    begin
    	insert into compte values(p_nom);
    	execute immediate 'create user ' || p_nom || ' identified by ' || p_nom;	
    end;
    /
     
    exec nouveau_compte('DEMO3');
    exec nouveau_compte('DEMO4');

  11. #11
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 104
    Par défaut
    merci beaucoup
    avec pragma autonomous_transaction;
    toujours des problemes
    mais la deuxieme méthode de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    DROP TRIGGER trig_compte;
     
    CREATE OR REPLACE procedure nouveau_compte(p_nom varchar2)
    IS
    begin
    	INSERT INTO compte VALUES(p_nom);
    	execute immediate 'create user ' || p_nom || ' identified by ' || p_nom;	
    end;
    /
     
    exec nouveau_compte('DEMO3');
    exec nouveau_compte('DEMO4');
    c bon je crée les utilisateurs
    une question : est ce que je peux appeler cette procédure dans mon trigger sans aucun problème, parce que j'avais essayé de créer l'utilisateur dans une procédure et appeler cette dernière dans un trigger, c'était pas bien le résultat

  12. #12
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Citation Envoyé par nouraty Voir le message
    ...
    une question : est ce que je peux appeler cette procédure dans mon trigger sans aucun problème, parce que j'avais essayé de créer l'utilisateur dans une procédure et appeler cette dernière dans un trigger, c'était pas bien le résultat
    Peu importe que vous exécutez le DDL directement dans le trigger ou dans une procédure appelée par le trigger, il y aurait toujours un commit implicite ce qui est interdit dans le trigger. C’est pour ça que vous devez soit utiliser les transactions autonomes, le commit s'effectue dans une autre transaction, soit passer par le package DBMS_JOB pour demander la création asynchrone de l’utilisateur, ce qui se fera dans une autre transaction bien sûr.
    Maintenant ce que vous propose Pomalaix est de complètement abandonner le trigger et de regrouper les deux actions dans une procédure que vous allez appeler à la place de l’insert dans votre table compte.

  13. #13
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 462
    Par défaut
    Citation Envoyé par nouraty Voir le message
    avec pragma autonomous_transaction;
    toujours des problemes
    Oui, et lesquels ? Tant que vous ne précisez pas votre source PL/SQL et le message d'erreur, on ne peut rien faire pour vous.

  14. #14
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 104
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    Oui, et lesquels ? Tant que vous ne précisez pas votre source PL/SQL et le message d'erreur, on ne peut rien faire pour vous.
    je voulais dire le même problème qu'avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERREUR à la ligne 1 :
    ORA-04098: Déclencheur  'ADMIN_BIB.CONN_USER' non valide. Echec de la
    revalidation
    Maintenant ce que vous propose Pomalaix est de complètement abandonner le trigger et de regrouper les deux actions dans une procédure que vous allez appeler à la place de l’insert dans votre table compte.
    oui c'est vrai, et même que ça ne soit pas le point avec lequel j'ai commencé ce n'est pas grave pour mon cas! du moins pas pour le moment.
    Je reviens sur les DBLS_JOB, un exemple simple pour leurs utilisation selon ce que j'ai compris:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     dbms_job.submit(
       what=>'ma_requete.sql;',
       next_date=>sysdate+1/24, -- start next hour
       interval=>'sysdate+1/24');  -- Run every hour
    je ne vois pas ici deja est ce que ma_requete.sql contiendra l'insertion dans la table, la création du user ou les deux! et puis avec le next_date et intervalle ça va se répéter après chaque intervalle !!

  15. #15
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Dans dbms_job vous n'envoyez que la partie non-transactionnelle : create user …
    L’exécution du dbms_job doit être immédiate et il n’y a aucune raison de ré exécuter ce job.

  16. #16
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 104
    Par défaut
    Citation Envoyé par mnitu Voir le message
    Dans dbms_job vous n'envoyez que la partie non-transactionnelle : create user …
    L’exécution du dbms_job doit être immédiate et il n’y a aucune raison de ré exécuter ce job.
    dans ce cas a quoi sert le interval=>'sysdate+1/24') et je suppose puisqu'on n'envoie que la partie non transactionnelle je dois l'appeler au moment de l'insertion n'est ce pas? alors comment faire?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/05/2011, 09h37
  2. Erreur dans mon trigger ?
    Par Metalyn dans le forum PL/SQL
    Réponses: 3
    Dernier message: 11/02/2008, 20h27
  3. [Trigger] Génération d'erreurs dans un trigger
    Par gilder89 dans le forum Développement
    Réponses: 5
    Dernier message: 10/04/2007, 12h02
  4. Erreur dans TRIGGER
    Par taroudant dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 02/08/2006, 14h31
  5. Gestion des erreurs dans un TRIGGER
    Par SDU64 dans le forum DB2
    Réponses: 1
    Dernier message: 18/05/2006, 09h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo