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 :

Problème de table mutante !


Sujet :

PL/SQL Oracle

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 10
    Points : 11
    Points
    11
    Par défaut Problème de table mutante !
    Voila j'ai réalisé un trigger, mais lorsque je le teste et que j'essaie de modifier ou d'insérer un ligne dans ma table, j'ai un problème de table mutante que je n'arrive pas à résoudre.

    Merci d'avance pour vos conseils avisés.

    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
     
    create or replace trigger Charge_ens
    after insert or update of duree on creneau
    for each row
    declare
    charge number;
    begin
    select max(sum(duree)) into charge from creneau
    group by noens;
    if charge > 20 then
    P_DEFICIT (:new.NOCLASSE, :new.NOMAT, :new.NOENS, :new.DUREE);
    insert into TEMP_CRENEAU values (:new.NOCREN);
    end if;
    end;
    /
    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
    25
    26
    27
     
    create or replace procedure P_DEFICIT (v_noclasse in NUMBER, v_nomat in NUMBER, v_noens in NUMBER, v_duree in NUMBER) is
    nbdef NUMBER;
    dureemaj NUMBER;
    begin
    select count(*) into nbdef
    from DEFICIT
    where v_noclasse=noclasse
    and v_nomat=nomat
    and v_noens=noens;
    if nbdef<>0 then
    select nb_heures_total into dureemaj
    from DEFICIT
    where v_noclasse=noclasse
    and v_nomat=nomat
    and v_noens=noens;
    dureemaj:=dureemaj+v_duree;
    update DEFICIT
    set nb_heures_total=dureemaj
    where v_noclasse=noclasse
    and v_nomat=nomat
    and v_noens=noens;
    else
    insert into DEFICIT values (v_noclasse, v_nomat, v_noens, v_duree);
    end if;
    end;
    /
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    update creneau set duree = 4 where nocren = 6;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    update creneau set duree = 4 where nocren = 6
    *
     
    ERROR at line 1:
    ORA-04091: table M1SID44.CRENEAU is mutating, trigger/function may not see it
    ORA-06512: at "M1SID44.CHARGE_ENS", line 4
    ORA-04088: error during execution of trigger 'M1SID44.CHARGE_ENS'

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

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Salut,
    As tu regardé les propositions de Pomalaix concernant la table mutante

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Oui oui j'ai déjà regardé cette page ... J'ai essayé d'appliquer les différentes solutions mais en vain ... je pense que quelque chose m'échappe.

  4. #4
    Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Quelques explications en anglais....
    http://asktom.oracle.com/tkyte/Mutate/

    Et n'oublie pas qu'un trigger est execute dans la meme trasaction que la table modifiee. Donc ton INSERT/UPDATE est toujours "en cours" quand le TRIGGER se lance.

    En d'autres mots, tu ne peux pas faire de SELECT sur la table/champs que tu es en train de modifier (duree dans creneau). Il faut que tu trouves une autre astuce pour mettre de cote ta somme avant de faire l'insert.

  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
    Points : 3 609
    Points
    3 609
    Par défaut
    Je pense que tu peux t'en sortir en utilisant 2 déclencheurs + une variable globale de package par exemple.

    - un trigger before insert or update => tu stockes dans ta variable de package la somme des durées

    - un trigger after insert or update for each row => tu remplace ton select sur créneau par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monpack1.som_duree := monpack1.som_duree + :new.duree;
    Un problème sans solution est un problème mal posé

    Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.

Discussions similaires

  1. Réponses: 17
    Dernier message: 15/10/2011, 01h30
  2. Problème de Table mutante sur un trigger
    Par mouad83 dans le forum SQL
    Réponses: 2
    Dernier message: 15/05/2009, 16h25
  3. Problème trigger : table mutante
    Par coboy dans le forum PL/SQL
    Réponses: 0
    Dernier message: 12/12/2008, 11h08
  4. Trigger, problème de table mutante
    Par waukine dans le forum PL/SQL
    Réponses: 7
    Dernier message: 24/04/2008, 16h03
  5. Réponses: 4
    Dernier message: 30/10/2005, 09h13

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