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 :

Trigger: table en mutation


Sujet :

Oracle

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    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.

  3. #3
    Membre Expert

    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 536
    Par défaut
    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

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Par défaut
    J'ai esayé ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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?

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Vous n'être plus très loin, il y a encore plus simple pour assigner une valeur, sans SELECT cette fois-ci.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Par défaut
    OK. Je n'ai pas trouvé...
    Ce serait vraiment sympa de me donner la solution

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    :new.TUBE_TRANCHEID := 1;

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Par défaut
    évidemment.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Par défaut
    Maintenant un peu plus compliqué:
    au lieu de mettre 1 dans :new.TUBE_TRANCHEID, je veux mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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?

  10. #10
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Vous aimez bien faire compliqué, vous aviez déjà écrit la bonne syntaxe un peu plus haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  11. #11
    Invité de passage
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 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;

    =========================

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

Discussions similaires

  1. Problème de trigger : table is mutating
    Par awalter1 dans le forum SQL
    Réponses: 6
    Dernier message: 08/02/2013, 23h11
  2. [Oracle8i][Trigger]Table en mutation
    Par Drizzt [Drone38] dans le forum Administration
    Réponses: 6
    Dernier message: 06/11/2009, 13h58
  3. Trigger & table "inserted"
    Par alexvdb dans le forum Développement
    Réponses: 11
    Dernier message: 29/12/2005, 00h43
  4. Curseurs et tables en mutation
    Par ze_patoche dans le forum Oracle
    Réponses: 7
    Dernier message: 18/10/2005, 10h58
  5. "self-referencing" + TRIGGER => table
    Par hair_peace dans le forum Oracle
    Réponses: 8
    Dernier message: 18/07/2005, 11h42

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