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

Administration Oracle Discussion :

[Oracle] variable :new dans les triggers


Sujet :

Administration Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 35
    Points : 33
    Points
    33
    Par défaut [Oracle] variable :new dans les triggers
    bonjour

    lors d'un insert, je souhaite appeler une procedure dans le trigger
    et passer la ligne insérée en argument de la procedure

    la table ttest (id int, lib varchar, name varchar);

    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
    CREATE OR REPLACE PROCEDURE p (r IN ttest%ROWTYPE)
    IS
    BEGIN
       DBMS_OUTPUT.put_line (r.lib);
    END;
    /
     
    CREATE OR REPLACE TRIGGER SUN.ttest_insert
       AFTER INSERT
       ON ttest
       REFERENCING NEW AS NEW
       FOR EACH ROW
    BEGIN
       /*DBMS_OUTPUT.put_line (:NEW.lib);*/
       p (:NEW);
    END;
    /
    /
    dans le cas présent, le trigger ne compile pas :
    PLS-00049: variable de lien erronée 'NEW'
    donc, y a t il moyen de lasser le :new entier en param, et non tous les attribut un par un (:new.id, :new.lib, :new.name) ???? (si oui comment?)

    l'exemple est bien entendu très simplifié, on résound le problème en collant le code de la procedure dans le trigger,
    mais j'utilise des procedures notamment pour mutualiser un peu de code, et que ça fait plus propre

    merci
    ++

  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
    Points : 3 609
    Points
    3 609
    Par défaut
    Non ce n'est pas possible.

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    quel est l'objectif ?

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 35
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par plaineR
    Non ce n'est pas possible.
    ça a le mérite d'être clair

    n'y aurait il pas de solutions détournées ?

    - le type de :new est bien ttest%ROWTYPE ?
    dans ce cas y aurait il moyen avec une sorte de boucle, de copier tous les atribut de new dans un nouvel objet de type ttest%ROWTYPE que je passerais en param à ma procedure ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 35
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par Fred_D
    quel est l'objectif ?
    l'objectif en version simplifiée: pour chaque ligne que j'insert(update,delete) dans la table T1, je veux que le trigger l'insert(update,delete) dans la table T2

    j'aurai passé simplement la clé primaire, mais il y avais le problème de la table mutante (ora-04091).
    et accessoierment, ça fait gagner un requête

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    alors regarde plutôt du coté des vues matérialisées

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 35
    Points : 33
    Points
    33
    Par défaut
    ok, d'après ce que j'ai pu comprendre des MATERIALIZED VIEW, la vue remplacerait ma 2e table
    il faut alors que je précise mon problème: je travaille sur une appli qui souffre de ses défauts de conception
    vu qu'on est en prod, la solution passe par des étapes intermédiaires.

    au départ il y avait une table Poject comme suit :
    table Project (id, name, desc,.... facility, specifications)

    puis ils ont décidé que pour un projet, on pouvait avoir jusqu'à 3 facilities,
    et au lieu de créer un table d'association project-facility, ils ont ajouté des colonnes dans la table project:
    table Project (id, name, desc,.... facility1, specifications1, facility2, specifications2, facility3, specifications3)

    et là, moi j'ai créé la table project-facility
    table project-facility(projectId, facilityId, orderId, specifications)
    remplie avec les colonnes correpondant de la table project

    en Prod, on remplit toujours dans la table project, mais avec des triggers je synchronise avec project-facility

    A terme les colonnes de project sauteront, et on remplira directement project-facility

    voilà
    ++

  8. #8
    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
    Dans ce cas, pourquoi ne pas faire dans un trigger after insert (global) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    insert into project-facility
    select ...
    from Project 
    where not exists (select null from project-facility where ...)

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Citation Envoyé par blackwizard
    et au lieu de créer un table d'association project-facility, ils ont ajouté des colonnes dans la table project
    Et là c'est le drame

    Citation Envoyé par blackwizard
    en Prod, on remplit toujours dans la table project, mais avec des triggers je synchronise avec project-facility
    et bien tu connais le nom des colonnes... pourquoi se casser la tête ?

    plaineR a raison, un INSERT ira très bien

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 35
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par plaineR
    Dans ce cas, pourquoi ne pas faire dans un trigger after insert (global) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    insert into project-facility
    select ...
    from Project 
    where not exists (select null from project-facility where ...)
    là je comprend pas bien ce que c'est supposé faire ..

    j'ai l'impression que je ne m'étais pas bien exprimé.

    la prod va continuer d'insérer des project avec les facility1 (et facility2, facility3, le cas échéant : environ 2% des projets demandent + de une facility)
    le trigger :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    insert into project-facility (projectid,facilityid,orderid,specifications)
    values (:new.projectid,:new.facilityid,(1,2 ou 3),:new.specifications)
    Citation Envoyé par Fred_D
    et bien tu connais le nom des colonnes... pourquoi se casser la tête ?
    plaineR a raison, un INSERT ira très bien
    oui, bien sur un insert, mais la question était de savoir comment récupérer les données à insérer, en l'occurence dans le :new, que je voulais passer en param d'une procedure

    sinon pour l'update, je voudrais mettre une condition pour ne faire l'opération que si les champs concernés ont changés
    dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update matable, set ...  where  ...
    seuls les champs spécifié dans "set" sont changé, comment on détecte ça ? (vu que la table à pour le moment 130 colonnes, elles sont pas toutes mise à jour en même temps).

    ça serait bon ça ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    when
    :old.facility1!=:new.facility1 ..

  11. #11
    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
    Citation Envoyé par blackwizard
    là je comprend pas bien ce que c'est supposé faire ..
    C'est supposé insérer tous les projets dans la table project-facilty qui n'y sont pas encore.

    Tu peux améliorer la chose en faisant une jointure, ou un trigger sur project-facility pour aller récupérer dans d'autres tables les informations manquantes.

    Après si tu veux passer par un trigger for each row, tu n'as pas d'autres solutions que de spécifier toutes les colonnes.

    Citation Envoyé par blackwizard
    ça serait bon ça ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    when
    :old.facility1!=:new.facility1 ..
    Sans les 2 points et avec des parenthèses, cela devrait fonctionner

  12. #12
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Points : 8 079
    Points
    8 079
    Par défaut
    Citation Envoyé par blackwizard
    ça a le mérite d'être clair

    n'y aurait il pas de solutions détournées ?

    - le type de :new est bien ttest%ROWTYPE ?
    dans ce cas y aurait il moyen avec une sorte de boucle, de copier tous les atribut de new dans un nouvel objet de type ttest%ROWTYPE que je passerais en param à ma procedure ?
    Feuerstein propose une procédure qui facilite la vie pour créer des déclencheurs permettant de passer en paramètre l'équivalent du :NEW.*
    Mais ça reste du statique, dépendant de la table concernée.
    http://examples.oreilly.com/oraclep3.../genTrigRec.sp

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 35
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par Pomalaix
    Feuerstein propose une procédure qui facilite la vie pour créer des déclencheurs permettant de passer en paramètre l'équivalent du :NEW.*
    Mais ça reste du statique, dépendant de la table concernée.
    http://examples.oreilly.com/oraclep3.../genTrigRec.sp
    finalement la solution est bien de dupliquer les attribut 1 par 1, mais
    merci, ça évite de taper des km de text, et il n'y a ps de risque de faute de frappe

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

Discussions similaires

  1. Type des variables :OLD et :NEW dans un trigger
    Par jproto dans le forum Débuter
    Réponses: 4
    Dernier message: 14/02/2008, 13h50
  2. [ Oracle 10g ] - XMLDB dans un trigger ORA-00600
    Par jacquesh dans le forum PL/SQL
    Réponses: 5
    Dernier message: 03/07/2007, 17h05
  3. [XSL~FO][FOP] variables possibles dans les attributs de tags ?
    Par lebechen dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 29/06/2006, 09h17
  4. [C++] Pb avec les variable static dans les classe
    Par quantik-revolution dans le forum C++
    Réponses: 3
    Dernier message: 03/03/2006, 18h40
  5. [XHTML] Variables contenus dans les messages en XHTML
    Par Linoa dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 19/09/2005, 12h45

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