Précédent   Forum des professionnels en informatique > Bases de données > Oracle > Débuter
Débuter Forum d'entraide pour débuter avec 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 07/07/2011, 10h02   #1
Membre du Club
 
Inscription : mars 2008
Messages : 227
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 227
Points : 44
Points : 44
Par défaut Trigger: table en mutation

Bonjour.
Je précise que je suis débutant avec les triggers.
Voilà le problème:
J'ai une table RELTUBES qui contient un champ identifiant TUBE_ID créé avec une séquence.
Cette table contient aussi un champ TUBE_GVID et un champ TUBE_TRANCHEID.
Lorsque j'ajoute ou modifie une ligne dans RELTUBES (en particulier le champ TUBE_GVID), je veux mettre la valeur 1 (je simplifie pour l'instant) dans le champ TUBE_TRANCHEID lorsque TUBE_GVID n'est pas NULL.

J'ai donc tapé ceci:
Code :
1
2
3
4
5
6
7
8
 
CREATE OR REPLACE TRIGGER METAJOURTRANCHE
after INSERT OR UPDATE of TUBE_GVID ON RELTUBES
FOR each row when (new.TUBE_GVID IS NOT NULL)
begin
UPDATE RELTUBES SET TUBE_TRANCHEID=1 WHERE TUBE_ID=:new.TUBE_ID;
end;
/
Mais j'ai le message d'erreur:
ORA-04091: la table UTILISATEURRELACHEMENT.RELTUBES est en mutation ; le déclencheur ou la fonction ne peut la voir

Comment faire?
Merci.
JCD21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 10h18   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 433
Points : 10 433
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
L'erreur provient d'un simple problème de logique.

Votre trigger se déclenche APRÈS insertion ou mise à jour.
Mais pendant votre trigger, vous lancez une mise à jour, qui va donc exécuter le trigger, qui va donc refaire une mise à jour...

Il faut donc que votre trigger s'exécute avant insertion ou mise à jour, et il suffit de modifier la nouvelle valeur de TUBE_TRANCHEID (une simple assignation, pas d'update nécessaire).

Je vous laisse chercher un peu pour la syntaxe.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 10h32   #3
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
Citation:
Envoyé par JCD21 Voir le message
Bonjour.
Mais j'ai le message d'erreur:
ORA-04091: la table UTILISATEURRELACHEMENT.RELTUBES est en mutation ; le déclencheur ou la fonction ne peut la voir

Comment faire?
Merci.
Bonjour,

La "Mutating Table error" est là pour vous protéger. Elle est là pour vous dire que votre logique n'est pas bonne.

Pour votre gouverne, lorsque vous crééz un trigger sur une table T et que le contenu de ce trigger fait un select/update sur la table T, sachez alors que votre logique n'est pas bonne.

De plus, si tant est que votre trigger n'est pas en erreur, avez-vous pensé, lors de la création de ce trigger, à l'impact qu'aura ce trigger sur une application mutli-users mutli-concurrente.

Moralité : faire très attention à l'aspect mutli-user lors de l'utilisation des triggers

Bien à vous

Mohamed Houri
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 10h59   #4
Membre du Club
 
Inscription : mars 2008
Messages : 227
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 227
Points : 44
Points : 44
J'ai esayé ce code:
Code :
1
2
3
4
5
6
7
8
 
CREATE OR REPLACE TRIGGER METAJOURTRANCHE
before INSERT OR UPDATE of TUBE_GVID ON RELTUBES
FOR each row when (new.TUBE_GVID IS NOT NULL)
begin
SELECT 1 INTO :new.TUBE_TRANCHEID FROM RELTUBES;
end;
/
mais j'ai cette erreur:
OCI_NO_DATA

Il n'est toujours pas bon mon trigger?
JCD21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 11h01   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 433
Points : 10 433
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Vous n'être plus très loin, il y a encore plus simple pour assigner une valeur, sans SELECT cette fois-ci.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 11h11   #6
Membre du Club
 
Inscription : mars 2008
Messages : 227
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 227
Points : 44
Points : 44
OK. Je n'ai pas trouvé...
Ce serait vraiment sympa de me donner la solution
JCD21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 11h22   #7
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 433
Points : 10 433
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Code :
:new.TUBE_TRANCHEID := 1;
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 11h27   #8
Membre du Club
 
Inscription : mars 2008
Messages : 227
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 227
Points : 44
Points : 44
évidemment.
JCD21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 11h53   #9
Membre du Club
 
Inscription : mars 2008
Messages : 227
Détails du profil
Informations forums :
Inscription : mars 2008
Messages : 227
Points : 44
Points : 44
Maintenant un peu plus compliqué:
au lieu de mettre 1 dans :new.TUBE_TRANCHEID, je veux mettre
Code :
SELECT GV_INTERVALLEENTRERGVID FROM RELGV WHERE GV_ID=:new.TUBE_GVID
où RELGV est une table qui a pour identifiant GV_ID et qui contient le champ GV_INTERVALLEENTRERGVID.
Cette requête ne renvoie qu'une valeur.
J'ai donc essayé :
Code :
1
2
3
4
5
6
7
CREATE OR REPLACE TRIGGER METAJOURTRANCHE
before INSERT OR UPDATE of TUBE_GVID ON RELTUBES
FOR each row when (new.TUBE_GVID IS NOT NULL)
begin
SELECT (SELECT GV_INTERVALLEENTRERGVID FROM RELGV WHERE GV_ID=:new.TUBE_GVID) INTO :new.TUBE_TRANCHEID FROM RELTUBES;
end;
/
mais j'ai le message d'erreur OCI_NO_DATA
puis :
Code :
1
2
3
4
5
6
7
CREATE OR REPLACE TRIGGER METAJOURTRANCHE
before INSERT OR UPDATE of TUBE_GVID ON RELTUBES
FOR each row when (new.TUBE_GVID IS NOT NULL)
begin
:new.TUBE_TRANCHEID := (SELECT GV_INTERVALLEENTRERGVID FROM RELGV WHERE GV_ID=:new.TUBE_GVID);
end;
/
mais ça ne passe pas à la compilation.
Que faut-il faire?
JCD21 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/07/2011, 11h58   #10
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 433
Points : 10 433
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Vous aimez bien faire compliqué, vous aviez déjà écrit la bonne syntaxe un peu plus haut :
Code :
1
2
3
SELECT GV_INTERVALLEENTRERGVID INTO :new.TUBE_TRANCHEID
  FROM RELGV
 WHERE GV_ID = :new.TUBE_GVID;
À mon avis ce que vous n'avez pas compris c'est que vous n'avez jamais besoin de faire référence à votre table RELTUBE dans votre trigger.
Toutes les colonnes existent, que ce soit les anciennes ou nouvelles valeurs avec les préfixes new et old.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/08/2011, 14h19   #11
Invité de passage
 
Homme Benj
Inscription : août 2011
Messages : 1
Détails du profil
Informations personnelles :
Nom : Homme Benj
Localisation : France

Informations forums :
Inscription : août 2011
Messages : 1
Points : 1
Points : 1
Par défaut trigger sur update

Bonjour

J'ai un trigger insert que je voudrais bien modifié pour en faire un update avez-vous une solution SVP ?
J'avoue que je suis perdu avec çà, j'ai même essayer de faire une table à coté. mais resultat néant. grr j'en perds mon latin c'est clair.
Merci d'avance pour votre aide.
=========================
create or replace
TRIGGER CAD_NUM_RUE
after
INSERT ON CAD_NUM_RUE
BEGIN

update CAD_NUM_RUE set CAD_NUM_RUE.adresse = CAD_NUM_RUE.num ||' '|| CAD_NUM_RUE.RUE;

END;

=========================
benj9025 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 21h44.


 
 
 
 
Partenaires

Hébergement Web