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

PL/SQL Oracle Discussion :

Pb Tables Mutantes sur Trigger et Autonomous_Transaction


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2005
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 42
    Par défaut Pb Tables Mutantes sur Trigger et Autonomous_Transaction
    Bonjour,

    J'ai des soucis avec un problème de table mutante, naturellement j'ai fait des recherches sur google et j'ai lu attentivement le tutoriel http://sgbd.developpez.com/oracle/ora-04091/

    J'ai simplifié mon problème en ce que je vous expose ci-après pour faciliter la compréhension, mais il s'agît également de ce que je suis en train de tester.

    Mes Tables :

    etudiant (id, nom, moyenne);
    matiere (id, note, id_etudiant);

    Je souhaiterai calculer la moyenne d'un étudiant à chaque fois qu'une note est modifiée (imaginons que toutes les notes dont j'ai besoin sont déjà insérées et initialisées). Pour cela on m'impose l'utilisation d'un Trigger.

    Mon Trigger sera appelé lors de l'utilisation d'un UPDATE de cette forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UPDATE matiere SET note = 20 WHERE id = xx;
    xx correspondant à l'id en base de la note modifiée.

    Voici le Trigger :

    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
    19
    20
    21
    22
    23
     
    create or replace
    TRIGGER TEST_TG
      AFTER UPDATE ON matiere 
       REFERENCING NEW as n
     FOR EACH ROW
     
    DECLARE
      idE integer;
      moyenne_generale number;
    BEGIN
     
    SELECT :n.id_etudiant INTO idE FROM dual;
     
            SELECT AVG(note) INTO moyenne_generale
              FROM matiere
              WHERE id_etudiant = idE;
     
          UPDATE etudiant
            SET moyenne = moyenne_generale
            WHERE id = idE;
     
    END;
    C'est donc là qu'apparait mon problème de table mutante, faisant un SELECT sur une table au moment où elle est modifiée.

    1ere remarque : Dans le tuto Développez.com, la méthode "E-4. Je suis grand, c'est moi qui gère" me fait sortir du Trigger sans modifier la moyenne.

    2eme remarque : Je préfère ne pas avoir recours aux autres méthodes de ce tutoriel (pour le moment...) pour diverses contraintes auxquelles je suis soumis.

    J'ai eu accès à un code semblable au mien qui marche en utilisant une directive PRAGMA AUTONOMOUS_TRANSACTION, de plus après des recherches cette solution semble effectivement marcher, et elle m'intéresse très fortement.

    J'ai donc modifié mon Trigger comme suit :

    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
    19
    20
    21
    22
    23
    24
     
    create or replace
    TRIGGER TEST_TG
      AFTER UPDATE ON matiere 
       REFERENCING NEW as n
     FOR EACH ROW
     
    DECLARE
      PRAGMA AUTONOMOUS_TRANSACTION;
      idE integer;
      moyenne_generale number;
    BEGIN
     
    SELECT :n.id_etudiant INTO idE FROM dual;
     
            SELECT AVG(note) INTO moyenne_generale
              FROM matiere
              WHERE id_etudiant = idE;
     
          UPDATE etudiant
            SET moyenne = moyenne_generale
            WHERE id = idE;
    COMMIT;
    END;
    Et là arrive ma véritable question : ce trigger a les mêmes effets qu'un BEFORE UPDATE, c'est à dire que la moyenne calculée est celle qui était vraie avant la modification d'une des notes.
    J'ai essayé de déplacer le COMMIT dans le trigger, et de le mettre partout dans le trigger (), même résultat.

    J'aimerais donc savoir si il y avait une explication à ce phénomène et si je pouvais y remédier (en gardant la solution des transactions autonomes qui semble marcher dans le même cas de figure sur d'autres applications...).

    Maintenant si vous me déconseillez cette méthode (même si jamais j'arrivai à la faire marcher), j'aimerai également savoir pourquoi (sachant qu'il s'agît d'une application multi-thread)

    Merci d'avance pour vos conseils

  2. #2
    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
    Chaque fois quand j'arrive à faire PRAGMA_AUTONOMOUS_TRANSACTION et COMMIT dans un trigger je me dit que je suis bien dans les choux et donc je change de solution.

  3. #3
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Une des solutions envisageables est de mémoriser les matières mises à jour (tableau, table temporaire, ...) dans un trigger for each row

    Puis dans un trigger after update global, de calculer les moyennes pour ces matières et de mettre à jour la table etudiant.

    Si tu peux passer par une table temporaire, il me semble que c'est la meilleure solution car elle sera automatiquement remise à vide au commit. Le tableau devra être lui remis à zéro.

  4. #4
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    une vue matérialisée en ajoutant la colonne moyenne qui se rafraichie ON_COMMIT me parait beaucoup mieux indiquer qu'un trigger.

    Eventuellement, tu peux peut-être créer une fonction en AUTONOMOUS TRANSACTION qui retourne la moyenne d'un éléve que tu appelleras dans ton trigger.

  5. #5
    Membre Expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Par défaut
    Citation Envoyé par orafrance Voir le message
    Eventuellement, tu peux peut-être créer une fonction en AUTONOMOUS TRANSACTION qui retourne la moyenne d'un éléve que tu appelleras dans ton trigger.
    Non cela ne marchera pas puisque avec ta fonction en autonomous_transaction tu verras la valeur de la note avant la mise à jour.

  6. #6
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    tu peux passer old et new en paramètre pour remplacer la valeur dans la fonction éventuellement

Discussions similaires

  1. Problème de Table mutante sur un trigger
    Par mouad83 dans le forum SQL
    Réponses: 2
    Dernier message: 15/05/2009, 16h25
  2. Table mutante et trigger
    Par maserati dans le forum Oracle
    Réponses: 1
    Dernier message: 09/02/2009, 16h50
  3. [10gXE][PL/SQL] trigger + table mutante
    Par <% Bastien %> dans le forum PL/SQL
    Réponses: 5
    Dernier message: 12/04/2007, 14h49
  4. Probleme trigger-tables mutantes
    Par scariou29 dans le forum Administration
    Réponses: 2
    Dernier message: 17/11/2006, 17h13
  5. [pl/sql] Trigger et table mutante
    Par claralavraie dans le forum Oracle
    Réponses: 20
    Dernier message: 18/07/2006, 15h41

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