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 :

La mystérieuse table mutante


Sujet :

PL/SQL Oracle

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 72
    Par défaut La mystérieuse table mutante
    Bonjour à tous,

    J'avais à l'origine le trigger suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE OR REPLACE TRIGGER schem0.JF_DEM_SXB
    after insert
    ON schem0.JF_DEMANDE FOR each row
    BEGIN
        IF :NEW.nr_quartier_elu is null and :NEW.nr_commune = '482' and :NEW.nr_grp_lot is not null
        THEN
           update jf_demande a set a.nr_quartier_elu = (select b.nr_quartier_elu from jf_grp_lot b
                                                 where  a.nr_grp_lot = b.nr_grp_lot )
        where a.nr_demande = :NEW.nr_demande;                                                         
        END IF;
     
    END;
    /
    ... pour mettre à jour le champ nr_quartier_elu d'une table lors de l'insertion d'une ligne.

    Or je me retrouve avec le message suivant :

    ORA-04091 : la table schem0.JF_DEMANDE est en mutation; le déclencheur ou la fonction ne peut la voir

    De fait, ça se produit quand on fait ce genre de choses sur une table comportant des clés étrangères.

    En farfouillant pas mal, j'ai trouvé une méthode conseillant de passer par une table temporaire intermédiaire et 2 triggers, alors j'ai écrit ça :

    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
     
    CREATE GLOBAL TEMPORARY TABLE TEMP_JF_DEMANDE AS SELECT * FROM JF_DEMANDE WHERE 0=1;
     
    CREATE OR REPLACE TRIGGER TEMP_JF_DEM_SXB BEFORE INSERT ON JF_DEMANDE FOR EACH ROW
    BEGIN
        INSERT INTO TEMP_JF_DEMANDE(NR_DEMANDE, NR_PRECEDENT, NR_PERSONNE, NR_GESTIONNAIRE, NR_MAIRIE, ABSENCE_REPONSE, DATE_DEMANDE, CONVOCATION, PREMIER_REFUS, SECOND_REFUS, 
            TEXTE_LIBRE_DEMANDE, RENOUVELLEMENT, DATE_MAJ, MATRICULE, DATE_DE_REMISE, TYJARDIN, NR_GRP_LOT, NR_COMMUNE, NR_QUARTIER_ELU) 
        VALUES (:NEW.NR_DEMANDE, :NEW.NR_PRECEDENT, :NEW.NR_PERSONNE, :NEW.NR_GESTIONNAIRE, :NEW.NR_MAIRIE, :NEW.ABSENCE_REPONSE, :NEW.DATE_DEMANDE, :NEW.CONVOCATION, :NEW.PREMIER_REFUS, :NEW.SECOND_REFUS, 
            :NEW.TEXTE_LIBRE_DEMANDE, :NEW.RENOUVELLEMENT, :NEW.DATE_MAJ, :NEW.MATRICULE, :NEW.DATE_DE_REMISE, :NEW.TYJARDIN, :NEW.NR_GRP_LOT, :NEW.NR_COMMUNE, :NEW.NR_QUARTIER_ELU);
    END ;
    /
     
    CREATE OR REPLACE TRIGGER JF_DEM_SXB_NEW AFTER INSERT ON TEMP_JF_DEMANDE
    BEGIN
        FOR LIGNE IN (SELECT * FROM TEMP_JF_DEMANDE ORDER BY NR_DEMANDE) LOOP
     
        IF LIGNE.nr_quartier_elu is null and LIGNE.nr_commune = '482' and LIGNE.nr_grp_lot is not null    
        THEN      
           execute immediate 'update jf_demande a set a.nr_quartier_elu = (select b.nr_quartier_elu from jf_grp_lot b where  a.nr_grp_lot = b.nr_grp_lot ) where a.nr_demande= ' || LIGNE.nr_demande ;               
            DBMS_OUTPUT.PUT_LINE('update jf_demande a set a.nr_quartier_elu = (select b.nr_quartier_elu from jf_grp_lot b where  a.nr_grp_lot = b.nr_grp_lot) where a.nr_demande= ' || LIGNE.nr_demande);                                                         
        END IF;
     
        END LOOP;            
       DELETE FROM TEMP_JF_DEMANDE;    
    END ;
    /

    Et alors ça ne plante pas, ça semble bien se dérouler, mais mais mon champ nr_quartier_elu n'est pas du tout mis à jour (en clair, l'update ne fait rien).
    Bizarre car le DBMS_OUTPUT.PUT_LINE que je fais juste en dessous me donne la requête que je m'attends à voir... et qui fait ce qu'il faut quand je la passe à la main.

    Au secours, je comprends plus...

  2. #2

  3. #3
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    Tu ne fais pas de "commit", ta transaction est-elle validée lorsque tu vérifies ta valeur ?

  4. #4
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Si ton trigger doit mettre à jour la ligne actuellement modifiée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE OR REPLACE TRIGGER schem0.JF_DEM_SXB
    BEFORE INSERT
    ON schem0.JF_DEMANDE FOR each row
    BEGIN
        IF :NEW.nr_quartier_elu IS NULL AND :NEW.nr_commune = '482' AND :NEW.nr_grp_lot IS NOT NULL
        THEN
          SELECT nr_quartier_elu INTO :new.a.nr_quartier_elu
          FROM jf_grp_lot
          WHERE  nr_grp_lot = :new.nr_grp_lot;
        END IF;
    EXCEPTION WHEN NO_DATA_FOUND THEN NULL; 
    WHEN  TOO_MANY_ROWS THEN NULL;
    END;
    /

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 72
    Par défaut
    Ouah, ça marche !
    T'es trop fort !

    Merci beaucoup !

  6. #6
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par marsup077 Voir le message
    T'es trop fort !
    Oui, je sais, je sais
    Plus sérieusement, c'est comme ça que ça s'utilise les triggers.

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

Discussions similaires

  1. [10gXE][PL/SQL] trigger + table mutante
    Par <% Bastien %> dans le forum PL/SQL
    Réponses: 5
    Dernier message: 12/04/2007, 14h49
  2. Probleme trigger-tables mutantes
    Par scariou29 dans le forum Administration
    Réponses: 2
    Dernier message: 17/11/2006, 17h13
  3. [pl/sql] Trigger et table mutante
    Par claralavraie dans le forum Oracle
    Réponses: 20
    Dernier message: 18/07/2006, 15h41
  4. Table Mutante
    Par chiheb dans le forum Oracle
    Réponses: 5
    Dernier message: 24/04/2006, 16h22
  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