Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/02/2011, 18h40   #1
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 53
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 53
Points : 13
Points : 13
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 :
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 :
1
2
 
INSERT INTO compte VALUES(3,'sara','sara','nulpart','sara@live.fr','sara',0,'p');
l'erreure:
Code :
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
nouraty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2011, 21h17   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 437
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 437
Points : 4 173
Points : 4 173
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.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 03h31   #3
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 53
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 53
Points : 13
Points : 13
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 :
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!
nouraty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 08h51   #4
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 311
Points : 5 808
Points : 5 808
Ç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 !
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 09h35   #5
Membre Expert
 
Avatar de Garuda
 
Homme Philippe CHIRCOP
Chef de projet
Inscription : juin 2007
Messages : 1 109
Détails du profil
Informations personnelles :
Nom : Homme Philippe CHIRCOP
Localisation : France

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

Informations forums :
Inscription : juin 2007
Messages : 1 109
Points : 1 559
Points : 1 559
Il manque un espace devant 'default tablespace'
__________________
Garuda गरूड
Brahmâ la Guerre et Vishnu la Paix

Oracle 10.2.0.4 - Forms6i patch 17 - Toad 11.1 - sharePoint 2010
Garuda est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 12h50   #6
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 437
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 437
Points : 4 173
Points : 4 173
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).
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 13h49   #7
Rédacteur
 
Inscription : décembre 2002
Messages : 2 385
Détails du profil
Informations personnelles :
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : décembre 2002
Messages : 2 385
Points : 3 261
Points : 3 261
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.
__________________
Consultant / formateur Oracle indépendant
Certifié OCP 10g et 11g, sécurité 11g
Pomalaix est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 14/02/2011, 14h01   #8
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 311
Points : 5 808
Points : 5 808
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 14/02/2011, 20h41   #9
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 53
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 53
Points : 13
Points : 13
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
nouraty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 23h04   #10
Rédacteur
 
Inscription : décembre 2002
Messages : 2 385
Détails du profil
Informations personnelles :
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : décembre 2002
Messages : 2 385
Points : 3 261
Points : 3 261
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 :
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 :
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');
__________________
Consultant / formateur Oracle indépendant
Certifié OCP 10g et 11g, sécurité 11g
Pomalaix est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/02/2011, 00h29   #11
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 53
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 53
Points : 13
Points : 13
merci beaucoup
avec pragma autonomous_transaction;
toujours des problemes
mais la deuxieme méthode de
Code :
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
nouraty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2011, 08h54   #12
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 311
Points : 5 808
Points : 5 808
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/02/2011, 10h22   #13
Rédacteur
 
Inscription : décembre 2002
Messages : 2 385
Détails du profil
Informations personnelles :
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : décembre 2002
Messages : 2 385
Points : 3 261
Points : 3 261
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.
__________________
Consultant / formateur Oracle indépendant
Certifié OCP 10g et 11g, sécurité 11g
Pomalaix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2011, 09h41   #14
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 53
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 53
Points : 13
Points : 13
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 :
1
2
3
ERREUR à la ligne 1 :
ORA-04098: Déclencheur  'ADMIN_BIB.CONN_USER' non valide. Echec de la
revalidation
Citation:
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 :
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 !!
nouraty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2011, 16h23   #15
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 311
Points : 5 808
Points : 5 808
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2011, 19h54   #16
Candidat au titre de Membre du Club
 
Inscription : octobre 2008
Messages : 53
Détails du profil
Informations forums :
Inscription : octobre 2008
Messages : 53
Points : 13
Points : 13
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?
nouraty est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h19.


 
 
 
 
Partenaires

Hébergement Web