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

Requêtes PostgreSQL Discussion :

Trigger entre 2 tables reliées 1 à n


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre régulier
    Trigger entre 2 tables reliées 1 à n
    Bonjour,

    voici deux tables :
    table1
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    id1(pk) objectid z
    0        1       100
    1        2       98

    table2
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    id2(pk) n_sd prof alt_inf
    0        1   5
    1        1   15
    2        2   8


    objectid fait reference à n_sd (1-n).
    L'objectif de la requête dans le trigger est de calculer au moment de l'insertion dans la table 2, la valeur de alt_inf qui est z-prof pour un objectid = n_sd.
    Ce qui donne de prime abord :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    IF (TG_OP = 'INSERT') THEN
    	NEW.alti_inf = (select z-NEW.prof from table1, table2
    	where table2.n_sd = table1.objectid )
       RETURN NEW;
    	END IF ;


    Le hic est que la sous-requête renvoie plusieurs lignes...
    J'ai trouvé une parade en créant une colonne dans table 2 qui insére le z de la table 1 pour chaque objectid et dont on se sert pour faire le calcul, mais je me demandais s'il n'y avait pas (sûrement) plus élégant, c'est à dire sans créer ce champ supplémentaire.
    Merci pour vos idées.

  2. #2
    Rédacteur/Modérateur

    Bonjour,

    Voici la sous-requête réécrite pour la limiter à la ligne en cours :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT z - NEW.prof 
    FROM table1
    INNER JOIN table2 ON table2.n_sd = table1.objectid
    WHERE table2.id2 = NEW.id2
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Membre régulier
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    WHERE table2.id2 = NEW.id2


    mmh jointure sur les id qui sont le clefs primaires ?? ce ne serait pas plutôt :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    WHERE table1.objectid = NEW.n_sondage


    ou j'ai rien compris, ce qui n'est pas exclut

  4. #4
    Rédacteur/Modérateur

    Les jointures s'écrivent dans la clause JOIN avec le mot-clef ON depuis 1992.
    Du coup, dans la requête que je vous ai donnée, la condition de jointure se trouve là :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    ON table2.n_sd = table1.objectid


    Ce qui est dans le WHERE, c'est le fait limiter la mise à jour à la seule ligne en cours d'insertion.
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  5. #5
    Membre régulier
    oui compris.
    Je me suis melangé les pinceaux dans le fil precedent. Desolé.
    Merci de me remettre du coté lumineux.

    Pour le moment ca ne me renvoie rien : ni résultat du calcul ni message d'erreur.
    Je continue à chercher.
    Merci

  6. #6
    Rédacteur/Modérateur

    Pour ma part, je n'aurais pas traité ça avec une sous-requête.
    J'aurais plutôt mis la valeur de Z de la table1 correspondante par une requête dans une variable (requête avec jointure ne renvoyant qu'une seule valeur), puis j'aurais mis à jour NEW.alt_inf avec cette variable et NEW.prof.
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  7. #7
    Membre régulier
    Voici le trigger mis à jour :

    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
    BEGIN
            -- A l'insert, calcul l'altitude inférieure
     
    	IF (TG_OP = 'INSERT') THEN
    	NEW.alti_inf = (select z-NEW.prof from table1 inner join table2 on objectid = n_sd
    			where table2.gid = NEW.gid) ;
            RETURN NEW;
    	END IF ;
    END;
    $$ 
    LANGUAGE plpgsql;
     
    DROP TRIGGER IF EXISTS trg_calcul_altiinf ON table2;
    CREATE TRIGGER trg_calcul_altiinf AFTER INSERT ON table2
        FOR EACH ROW EXECUTE PROCEDURE calcul_altiInf();


    Quand j'insère un enregistrement, rien ne se passe. Que le TRIGGER soit AFTER ou BEFORE.
    Quand je teste en remplaçant NEW.gid par un chiffre, ca ne fonctionne pas non plus.

    Une idée du pourquoi ?
    Merci

  8. #8
    Membre régulier
    J'ai fait autrement :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IF (TG_OP = 'INSERT') THEN
    	NEW.alti_inf = (select z - NEW.prof from table1 where NEW.n_sd = objectid) ;
            RETURN NEW;
    	END IF ;


    Cela fonctionne.