#1 Wed 14 December 2016 16:10
- legannec
- Participant occasionnel
- Lieu: Sainte-Marie-Aux-Mines
- Date d'inscription: 8 Aug 2011
- Messages: 39
trigger : mise à jour d'une donnée entre deux tables
Bonjour,
J'ai un léger problème pour mettre à jour une donnée dans une table A depuis une nouvelle donnée d'une table B.
Nous sommes dans la thématique d'un parc d'éclairage public, le but est de récupérer une date d'intervention de changement d'ampoule sur un point lumineux.
Dans un schéma ep, on trouve :
une table ep_support avec un champ code_point_lumineux contenant un identifiant unique pour chaque objet et un champ date_lampe qui comprend la dernière date de changement d'ampoule.
une autre table ep_entretien avec à nouveau le champ code_point_lumineux pour la mise en relation et un champ date_intervention à remplir lors d'un changement d'ampoule.
L'objectif est de remonter automatiquement la dernière date de changement d'ampoule de la table ep_entretien vers la table ep_support
Ce qui m’amène à deux difficultés :
- d'abord le trigger que je n'arrive pas à faire fonctionner lorsque l'on ajoute une nouvelle intervention :
Code:
-- Trigger: date_entretien on ep.ep_entretien -- DROP TRIGGER date_entretien ON ep.ep_entretien; CREATE TRIGGER date_entretien AFTER INSERT ON ep.ep_entretien FOR EACH ROW EXECUTE PROCEDURE retourne_date(); -- Function: retourne_date() -- DROP FUNCTION retourne_date(); CREATE OR REPLACE FUNCTION retourne_date() RETURNS trigger AS $BODY$ BEGIN update ep_support SET date_lampe = new.date_intervention where ep_support.code_point_lumineux = ep_entretien.code_point_lumineux; return new ; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION retourne_date() OWNER TO postgres;
- ensuite, pour un point lumineux avec un identifiant unique il pourrait avoir eu plusieurs changement d'ampoule à des dates différents, comment récupérer uniquement la dernière date d'intervention ?
Merci d'avoir pris le temps de lire ce post,
legannec, Sigiste à la com'com du Val d'Argent
Hors ligne
#2 Wed 14 December 2016 16:52
Re: trigger : mise à jour d'une donnée entre deux tables
Bonjour,
Si je comprends bien :
- la table ep_support contient autant d'enregistrements que de supports avec comme clé primaire la colonne code_point_lumineux
- la table ep_entretien contient autant d'enregistrements que d'interventions (donc plusieurs enregistrements pour le même point lumineux identifié de manière unique par la colonne code_point_lumineux
Il faut utiliser NEW.code_point_lumineux au lieu de ep_entretien.code_point_lumineux
Code:
Code: -- Trigger: date_entretien on ep.ep_entretien -- DROP TRIGGER date_entretien ON ep.ep_entretien; CREATE TRIGGER date_entretien AFTER INSERT ON ep.ep_entretien FOR EACH ROW EXECUTE PROCEDURE retourne_date(); -- Function: retourne_date() -- DROP FUNCTION retourne_date(); CREATE OR REPLACE FUNCTION retourne_date() RETURNS trigger AS $BODY$ BEGIN UPDATE ep_support SET date_lampe = NEW.date_intervention WHERE ep_support.code_point_lumineux = NEW.code_point_lumineux; RETURN new ; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION retourne_date() OWNER TO postgres;
Concernant la question des changements d'ampoule multiples sur le même point lumineux, elle est sans objet étant donné que le trigger traite toujours la dernière intervention (celle qui vient d'être insérée.)
Dernière modification par jmarsac (Wed 14 December 2016 16:57)
Jean-Marie
Azimut
Hors ligne
#3 Wed 14 December 2016 18:26
- JD
- Moderateur
- Date d'inscription: 8 Aug 2013
- Messages: 726
Re: trigger : mise à jour d'une donnée entre deux tables
Concernant la question des changements d'ampoule multiples sur le même point lumineux, elle est sans objet étant donné que le trigger traite toujours la dernière intervention (celle qui vient d'être insérée.)
En supposant que les dates d'intervention soient rentrées dans l'ordre chronologique, ce qui est souvent le cas.
Hors ligne
#4 Wed 14 December 2016 18:38
Re: trigger : mise à jour d'une donnée entre deux tables
Oui, c'est ce que j'ai (peut-être abusivement) supposé en oubliant de l'indiquer. Merci de l'avoir précisé.
Dernière modification par jmarsac (Wed 14 December 2016 19:12)
Jean-Marie
Azimut
Hors ligne
#5 Thu 15 December 2016 10:57
- legannec
- Participant occasionnel
- Lieu: Sainte-Marie-Aux-Mines
- Date d'inscription: 8 Aug 2011
- Messages: 39
Re: trigger : mise à jour d'une donnée entre deux tables
Bonjour et merci pour vos retours !
Malheureusement, il reste un problème :
Erreurs de commit :
Code:
Impossible de valider les changements pour la couche ep_entretien Erreurs : ERREUR : 1 attribut non-ajouté. Erreur du fournisseur de données : Erreur PostGIS lors de l'ajout d'entité : ERREUR: la relation « ep_support » n'existe pas LINE 1: UPDATE ep_support SET date_lampe = NEW.date_intervention ^ QUERY: UPDATE ep_support SET date_lampe = NEW.date_intervention WHERE ep_support.code_point_lumineux = NEW.code_point_lumineux CONTEXT: fonction PL/pgsql retourne_date(), ligne 4 à instruction SQL
Ce que je n’avais pas précisé, c'est la façon dont est récupéré le code_point_lumineux dans la table ep_entretien : c'est tout simplement un autre trigger basé sur un critère de distance :
Code:
-- Trigger: entretien on ep.ep_entretien -- DROP TRIGGER entretien ON ep.ep_entretien; CREATE TRIGGER entretien BEFORE INSERT OR UPDATE ON ep.ep_entretien FOR EACH ROW EXECUTE PROCEDURE retourne_code(); -- Function: retourne_code() -- DROP FUNCTION retourne_code(); CREATE OR REPLACE FUNCTION retourne_code() RETURNS trigger AS $BODY$ BEGIN select into new.code_point_lumineux ep_support."code_point_lumineux", st_distance(new.geom, ep_support.geom) from ep.ep_support order by 2 LIMIT 1; return NEW; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION retourne_code() OWNER TO postgres;
Peut-être que que le problème de relation est lié ? et/ou alors que c'est au niveau du déclenchement du trigger ?...
...des idées ?
legannec, Sigiste à la com'com du Val d'Argent
Hors ligne
#6 Thu 15 December 2016 11:13
- Ben22
- Participant actif
- Lieu: 33
- Date d'inscription: 11 May 2016
- Messages: 96
Re: trigger : mise à jour d'une donnée entre deux tables
peut-être manque t-il l'indication du schéma dans l'update de la fonction ? :
Code:
Code: Code: -- Trigger: date_entretien on ep.ep_entretien -- DROP TRIGGER date_entretien ON ep.ep_entretien; CREATE TRIGGER date_entretien AFTER INSERT ON ep.ep_entretien FOR EACH ROW EXECUTE PROCEDURE retourne_date(); -- Function: retourne_date() -- DROP FUNCTION retourne_date(); CREATE OR REPLACE FUNCTION retourne_date() RETURNS trigger AS $BODY$ BEGIN UPDATE ep.ep_support SET date_lampe = NEW.date_intervention WHERE ep_support.code_point_lumineux = NEW.code_point_lumineux; RETURN new ; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION retourne_date() OWNER TO postgres;
Edit :
Si tu souhaites que seule la dernière date d'intervention soit prise en compte :
Code:
CREATE OR REPLACE FUNCTION retourne_date() RETURNS trigger AS $BODY$ BEGIN update ep.ep_support SET date_lampe =(SELECT max(date_intervention) FROM ep.ep_intervention WHERE code_point_lumineux = NEW.code_point_lumineux) As t1 WHERE ep_support.code_point_lumineux = NEW.code_point_lumineux; RETURN new ; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;
Dernière modification par Ben22 (Thu 15 December 2016 11:36)
Hors ligne
#7 Thu 15 December 2016 11:37
- legannec
- Participant occasionnel
- Lieu: Sainte-Marie-Aux-Mines
- Date d'inscription: 8 Aug 2011
- Messages: 39
Re: trigger : mise à jour d'une donnée entre deux tables
C'était exactement ça Ben22, le trigger et sa fonction tournent !
Merci encore à vous 3 !
legannec, Sigiste à la com'com du Val d'Argent
Hors ligne