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 After Update


Sujet :

Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 98
    Par défaut Trigger After Update
    Salut tout l'monde

    j'ai créé un trigger tout simple en "AFTER UPDATE on MATABLE".
    Ce trigger lance une fonction asynchrone qui me renvoie la valeur de "mon_champs" du record qui vient d'être updaté.

    Probleme: "mon_champs" est encore à l'ancienne valeur.

    Questions: est-ce que je dois faire un commit alors que le TRIGGER est en AFTER UPDATE ? ou autre chose ?

    Merci

    Note: Je suis en 8i

    CREATE OR REPLACE TRIGGER TRIG_MATABLE_AFTER_IU
    AFTER INSERT OR UPDATE
    ON MATABLE
    FOR EACH ROW
    DECLARE
    FA_TRANSPORTABLE NUMBER;
    BEGIN
    IF UPDATING THEN FA_TRANSPORTABLE:=FUNC_MATABLE_GET_TRANSP(:new.ID);
    END IF;
    END;
    CREATE OR REPLACE FUNC_MATABLE_GET_TRANSP(FA_ID NUMBER)
    RETURN NUMBER
    IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    FA_TRANSPORTABLE NUMBER;
    BEGIN
    SELECT TRANSPORTABLE INTO FA_TRANSPORTABLE
    FROM MATABLE
    WHERE ID =FA_ID ;
    dbms_output.put_line( 'test'||' return: '||FA_ID ||' '||FA_TRANSPORTABLE);
    RETURN FA_TRANSPORTABLE;
    END;

  2. #2
    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
    et pourquoi pas simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF UPDATING THEN FA_TRANSPORTABLE:=:new.TRANSPORTABLE; 
    END IF;

  3. #3
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    C'est normal car votre fonction démarre une transaction indépendante (PRAGMA AUTONOMOUS_TRANSACTION) qui ne peut pas lire les modifications de la transaction courante. Si vous otez cette directive, vous aurez probablement l'erreur "table mutante" ...

  4. #4
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 98
    Par défaut
    Tout d'abord, merci à vous deux plaineR et pifor

    Pour
    IF UPDATING THEN FA_TRANSPORTABLE:=:new.TRANSPORTABLE;
    END IF;
    ca ne correspond pas à mes besoins... l'exemple que j'ai donné sert seulement à tester la valeur au moment du trigger mais en fait, c'est une autre fonction qui renverra TRANSPORTABLE sur base d'un ID...

    Merci pour la précision pifor !!!

    Donc, il n'y a aucun moyen de récupérer (lors de la transaction) les nouvelles valeurs...

    Bin, merci encore !!!
    ++
    HH

  5. #5
    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
    mais :new.TRANSPORTABLE est bien la nouvelle valeur de la colonne... je ne comprends pas ce qui géne

  6. #6
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    98
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 98
    Par défaut
    Comme je disais, l'exemple est pour le teste.

    En fait, j'ai des objets, qui en contiennent d'autres. J'ai donc une table qui se référence elle-meme.

    Structure+champ Transportable:
    NomTransportable
    PC1 1
    --Carte Mere 1
    --Transfo 1
    PC2 0
    --Carte Mere 0
    --Transfo 0
    Si un contenant est transportable, son contenu aussi.
    (1.) Je dois empecher la modification du champ (transportable) pour les "contenu".
    (2.) Si on modifie le champ d'un "contenant", on modifie celui des "contenu"

    Voila pour le principe

    Si j'applique (1.), il sera impossible de répercuter la modification.
    J'ai donc créer un trigger (qui appelle une fonction) qui prend la valeur du parent avant l'update:

    (3) UPDATE Carte Mere du PC1 transportable=0: il cherche transportable du parent (ici PC1) et le réaffecte (transportable -> 1)
    Le probleme est que si je répercute, le trigger prendra la valeur du parent mais avant la modification.

    UPDATE PC1 transportable=0. Répercute: (3) car PC1 transportable n'est pas encore à 0
    Je sais pas si c'est clair mais si qqun comprend et a une idée....(je peux continuer à préciser s'il faut)

    (Existe-t-il un TRIGGER "AFTER COMMIT" ???)

    Merci
    HH

  7. #7
    Membre Expert

    Profil pro
    Inscrit en
    Février 2006
    Messages
    3 437
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 3 437
    Par défaut
    Il n'y a pas de trigger "AFTER COMMIT" mais il existe des solutions pour contourner le problème de la table mutante: voir http://sgbd.developpez.com/oracle/ora-04091/

  8. #8
    Membre Expert
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Par défaut
    Citation Envoyé par hair_peace
    (Existe-t-il un TRIGGER "AFTER COMMIT" ???)
    ... Non mais il existe un trigger "FOR EACH STATEMENT" qui lui véra tes modifs.

    Un petit problème sur ce genre de trigger, c'est qu'il n'y a pas de notion de :new ou :old (ok c'est même un gros problème!).
    Dans d'autres bases de données comme sybase, il y a une pseudo-table qui contient toutes les modifications. En oracle, une telle table n'existe pas, il faut donc la fabriquer et la remplir toi même.

    l'idée, c'est donc de:
    - creer un table temporaire un fois pour toute
    - faire un trigger "after (ou before) update for each row" qui aura pour seule fonction de remplir ta table temporaires avec tes données utiles (valeurs :old, :new etc...)
    - faire un trigger "after update for each statement" dans lequel tu pourras faire tes traitements en fonction des valeurs contenenues dans ta table temporaire.

Discussions similaires

  1. trigger after update question!
    Par touille dans le forum PL/SQL
    Réponses: 1
    Dernier message: 27/07/2009, 17h37
  2. Trigger After Update avec la table Deleted vide ?
    Par azur668 dans le forum Développement
    Réponses: 4
    Dernier message: 24/06/2009, 23h41
  3. Problème exécution trigger after update
    Par Fabien85 dans le forum Développement
    Réponses: 19
    Dernier message: 15/01/2009, 17h35
  4. Réponses: 5
    Dernier message: 15/06/2007, 16h05
  5. TRIGGER After Update
    Par Nounoursonne dans le forum Oracle
    Réponses: 8
    Dernier message: 20/07/2005, 13h33

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