#1 Thu 27 May 2021 21:50
- Demonshine
- Participant occasionnel
- Date d'inscription: 27 May 2021
- Messages: 21
Trigger jointure entre deux tables (relation 1 à n)
Bonjour,
Je rencontre un problème sur la mise en place d'un trigger entre deux tables d'une base de données postgresql.
Je dispose de deux tables :
Table 1 : Toponymie_activites (champs : geom, fid, id, classe, nature, graphie, source, statut_top, date_top) de type PONCTUEL et Table 2 de type POLYGONE : ZAI (geom, id, fid, nature, nat_detail, toponyme, statut_top, importance...)
Le but est de récupérer les mises à jour ou insertions qui seraient faites sur le champ "toponyme" de la table 2 si celui-ci n'est pas null et de récupérer également les champs de cette même table : id, nature et geom associés au toponyme. Il s'agit de champs communs dont j'aimerais garder l'information et qui me permettraient de faire le lien entre ces deux tables : nature, id, graphie (=toponyme dans ZAI) et geom (faire le calcul st_centroid(geom) pour obtenir un ponctuel) dans ZAI
Ces modifications devront se répercuter de manière automatisée dans la table 1 et donc dans la base de données par l'ajout d'une nouvelle ligne par toponyme dans la table.
Étant débutant sur la mise en place de triggers, je n'ai abouti à aucun résultat. Je vous partage tout de même une de mes tentatives de création de triggers.
Code:
DELIMITER $$ CREATE TRIGGER maj_zai AFTER INSERT OR UPDATE ON ZAI FOR EACH ROW BEGIN NEW.id:= (SELECT id FROM toponymie_activites WHERE id = NEW.id); RETURN NEW; NEW.nature:= (SELECT nature FROM toponymie_activites WHERE nature = NEW.nature); RETURN NEW; NEW.graphie:= (SELECT graphie FROM toponymie_activites WHERE graphie = NEW.toponyme); RETURN NEW; NEW.geom:= (SELECT geom FROM toponymie_activites WHERE geom = NEW.st_centroid(geom); RETURN NEW; end; DELIMITER;
Merci d'avance pour votre aide !!
Hors ligne
#2 Fri 28 May 2021 11:33
- JP LLORENS
- Participant assidu
- Date d'inscription: 12 Nov 2008
- Messages: 231
Re: Trigger jointure entre deux tables (relation 1 à n)
Bonjour.
Votre trigger est lancé depuis la table 2 et met à jour cette même table.
Les valeurs NEW.XXX font référence aux valeurs des colonnes de la table appelante.
Dans votre trigger il faut lancer un update de la table 1.
Exemple :
Code:
BEGIN -- A chaque modification d'une conformité on va mettre à jour la référence du dossier, le libelle et la date dans la table des précontentieux update infractions_precontentieux set id_conformite = NEW.id_conformite_travaux , date_conformite = NEW.date_conformite, libelle = NEW.libelle where infractions_precontentieux.dossier_regul = NEW.nom_dossier; return NEW;
Les NEW.XXX sont les valeurs de la table 2 que l'on bascule dans la table 1.
Mais attention, l'update va fonctionner que si l’identifiant servant de jointure dans la ligne de la table 2 existe dans la table 1.
Il faut tester au préalable le statut du trigger (en INSERT ou UPDATE) avec la variable TG_OP :
Code:
IF TG_OP = 'INSERT' THEN insert into table1.. ELSEIF TG_OP = 'UPDATE' THEN update table1 set... END IF;
En fonction du statut vous adapterez les actions (insert ou update dans la table 1) à réaliser
Cordialement
JP
PS : votre post n'est pas dans le bon forum => Géo'BD
Hors ligne
#3 Mon 31 May 2021 08:47
- Demonshine
- Participant occasionnel
- Date d'inscription: 27 May 2021
- Messages: 21
Re: Trigger jointure entre deux tables (relation 1 à n)
Bonjour,
Je vous remercie pour votre retour très complet. Votre exemple me permet de mieux comprendre mon erreur.
Cordialement,
Hors ligne
#4 Thu 03 June 2021 15:23
- Demonshine
- Participant occasionnel
- Date d'inscription: 27 May 2021
- Messages: 21
Re: Trigger jointure entre deux tables (relation 1 à n)
Bonjour,
J'ai tenté de refaire mon trigger sur la base de votre exemple mais un élément a dû m'échapper car cela ne marche toujours pas. Voici mon code :
Code:
CREATE OR REPLACE FUNCTION maj_zai() RETURNS trigger AS $BODY$ DECLARE BEGIN IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN UPDATE toponymie_activites set graphie = NEW.toponyme, nature = NEW.nature, geom=NEW.st_centroid(geom) FROM ZAI WHERE id = NEW.id; END IF; return NEW; END; $BODY$ LANGUAGE plpgsql; CREATE TRIGGER trigger_maj_zai AFTER INSERT OR UPDATE ON ZAI FOR EACH ROW EXECUTE PROCEDURE maj_zai();
Les valeurs NEW.XXX représentant les valeurs de la table modifiée : ZAI.
Merci par avance pour votre aide !
Hors ligne
#5 Thu 03 June 2021 17:57
- JP LLORENS
- Participant assidu
- Date d'inscription: 12 Nov 2008
- Messages: 231
Re: Trigger jointure entre deux tables (relation 1 à n)
Bonjour.
En fait il doit y avoir 2 actions différentes suivant que soyez en INSERT ou UPDATE.
La close WHERE id = NEW.id ne peut fonctionner que si l'id existe dans la table toponymie_activites. Ce qui ne doit pas être votre cas quand vous faites un INSERT, donc il faut avoir qq chose du genre :
Code:
IF TG_OP = 'UPDATE' THEN UPDATE toponymie_activites set graphie = NEW.toponyme, nature = NEW.nature, geom=st_centroid(NEW.geom) FROM ZAI WHERE id = NEW.id; ELSEIF TG_OP = 'INSERT' THEN INSERT into toponymie_activites (graphie ,nature ,geom,id) values (NEW.toponyme, NEW.nature,st_centroid(NEW.geom),NEW.id) END IF;
Il faut peut être affiner la requête mais le résultat doit ressembler à ça.
Cordialement
JP
Hors ligne
#6 Fri 04 June 2021 11:08
- Demonshine
- Participant occasionnel
- Date d'inscription: 27 May 2021
- Messages: 21
Re: Trigger jointure entre deux tables (relation 1 à n)
Bonjour,
Merci beaucoup pour ton aide JP, mon trigger fonctionne !
Hors ligne