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 :

Problème de table mutante - count dans le trigger appliqué à la même table


Sujet :

Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Inscrit en
    Avril 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 22
    Par défaut Problème de table mutante - count dans le trigger appliqué à la même table
    Bonjour à tous,
    Je sais que ce problème a été reporté mainte fois, mais je n'arrive pas à trouver une solution sans pour autant avoir à créer d'autre package ou
    d'autre trigger, ou une table temporaire..

    J'ai le trigger suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE OR REPLACE TRIGGER company_class_pre_ins
    BEFORE INSERT  ON g_dosser 
    FOR EACH ROW
    ....
    SELECT COUNT(*)
    INTO existing_doss_cnt
    FROM g_dosser doss
    WHERE doss.doss_num= :new.doss_num
    AND   doss.doss_type= :new.doss_type;

    et un autre trigger qui contient la requête suivante (donc lorsqu'on a un tel insert le premier trigger se déclenche)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO g_dosser(
                    doss_num,
                    doss_type,
                    doss_code,
                    doss_group_code,
                    doss_id_fl)    
    SELECT      :new.dbd_num,
                    dbd_type,
                    decode( dbd_ind, 'i', 'itnn', 'a', 'itnn', NULL ),
                    decode( dbd_ind, 'b', 'rppd', 'a', 'rppd', NULL ),
                    'n'
    FROM    dbd_type
    WHERE   :new.dbd_flag = 'y';
    je reçois effectivement l'erreur ORA-20700: ORA-04091 table is mutating...

    je sais que le problème provient du premier count(*) puisqu'il est appliqué sur la table elle même, mais je n'arrive pas à contourner cette erreur
    Merci pour votre aide

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Si je ne m'abuse, il faut faire ton select dans une "autonomous transaction", c'est à dire une transaction extérieure à la transaction actuelle. Attention cependant, cela implique qu'elle n'a pas accès aux données que tu es en train de modifier.

  3. #3
    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
    Il y a un tutoriel sur le problème de la table mutante sur ce site, mais le meilleur c’est de ne pas utiliser les triggers dans ce cas.

  4. #4
    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
    Comme toujours, que vaudrait votre count(*) dans un environnement multi-users?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT COUNT(*)
    INTO existing_doss_cnt
    FROM g_dosser doss
    WHERE doss.doss_num= :new.doss_num
    AND   doss.doss_type= :new.doss_type;
    L'erreur "ORA-20700: ORA-04091 table is mutating" est là pour vous protéger et non pour vous géner.

    Si vous embarquez dans cette direction en voulant éviter l'erreur de la table mutante en y ajoutant une dose de transaction autonome, vous êtes alors dans une mauvaise direction.

  5. #5
    Membre actif
    Inscrit en
    Avril 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 22
    Par défaut
    Je ne comprends pas votre question Mohamed.

    je fais actuellement ce count, parce que aprés j'ai des contrôles à faire sur le type de dossier à insérer,
    certains types devront être unique.

    Juste une remarque, lorsque je fais un simple insert
    insert into g_dossier values (....)
    je n'ai pas le problème de la table mutante.

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    je fais actuellement ce count, parce que aprés j'ai des contrôles à faire sur le type de dossier à insérer, certains types devront être unique.
    Comment sont déterminés les types qui devoivent être uniques ?
    Si la condition est simple et surtout déterministe, alors un FBI (Function Based Indexes) devrait résoudre le problème.
    Juste une remarque, lorsque je fais un simple insert
    insert into g_dossier values (....)
    je n'ai pas le problème de la table mutante.
    Dans quelles circonstances l'erreur ORA-04091 se produit-elle ?

    Mais je pense comme Mnitu et Mohamed que le mieux est d'éviter les triggers dans ce cas, surtout si la contrainte s'exprime facilement.

  7. #7
    Membre actif
    Inscrit en
    Avril 2009
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 22
    Par défaut
    Merci pour votre réponse skuatamad,
    En fait, j'ai deux trigger, c'est dans le premier (table b_organisation) qu'il y'a un insert en masse (INSERT INTO g_dosser ... select * from dbd_type) qui déclenche le deuxième trigger sur la table (g_dosser) , d'ou le count(*)
    le type de dossier qui doit être unique est comparé en dur genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    IF existing_doss_cnt >0
        THEN
         IF :new.doss_type = 'CHG'
    ....
     
    ELSE
      --- type de dossier autre que CHG ne doit pas être multiple.
       RAISE err;
    END IF;
    END IF;

    comme signalé, si c'est un insert simple je n'ai pas le problème de la table mutante, ceci se déclenche juste avec l'insert en masse.

  8. #8
    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
    Si votre but est d'eviter des doublons de dossiers alors

    (a) implémentez une contraint unique sur le dossier
    ou
    (b) un index unique (peut-être dans votre case un function based index)

    Ainsi, vous n'aurez pas à vous souciez du problème de concurrence lorsque deux utilisateurs voudront ajouter le même dossier. Le deuxième attendra la fin du travail du premier avant soit d'être rejeté grâce à (a) ou (b) ou que son insert soit accepté à cause du fait que le premier user a fait un rollback;

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

Discussions similaires

  1. Problème de droits d'éxécution dans un trigger
    Par Xavinou57 dans le forum PL/SQL
    Réponses: 3
    Dernier message: 05/11/2009, 20h43
  2. Count dans plusieurs colonne d'une même table
    Par macfleid dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/07/2008, 20h43
  3. Trigger sur une même table
    Par lamanoo dans le forum DB2
    Réponses: 6
    Dernier message: 29/08/2007, 17h01
  4. Réponses: 2
    Dernier message: 13/06/2007, 12h29
  5. Réponses: 1
    Dernier message: 28/03/2007, 12h23

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