Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

GeoRezo est partenaire média de la Conférence Francophone SIG 2017 organisée par ESRI.

Les bénévoles de l'association seront présents les 11 et 12 Octobre aux Docks de Paris.

Le programme est riche, mais vous trouverez bien un  moment pour venir faire une pause au stand GeoRezo, et rencontrer les animateurs du portail francophone de la géomatique.

Nous serons à votre écoute pour partager avec vous notre passion pour l’animation du portail GeoRezo.

L'équipe GeoRezo

#1 mer. 14 décembre 2016 16:10

legannec
Membre
Lieu: Sainte-Marie-Aux-Mines
Date d'inscription: 8 août 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 mer. 14 décembre 2016 16:52

jmarsac
Membre
Lieu: NICE
Date d'inscription: 26 oct. 2005
Messages: 212
Site web

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 (mer. 14 décembre 2016 16:57)


Jean-Marie

Hors ligne

 

#3 mer. 14 décembre 2016 18:26

lejedi76
Membre
Date d'inscription: 8 août 2013
Messages: 225

Re: trigger : mise à jour d'une donnée entre deux tables

jmarsac a écrit:

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 mer. 14 décembre 2016 18:38

jmarsac
Membre
Lieu: NICE
Date d'inscription: 26 oct. 2005
Messages: 212
Site web

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 (mer. 14 décembre 2016 19:12)


Jean-Marie

Hors ligne

 

#5 jeu. 15 décembre 2016 10:57

legannec
Membre
Lieu: Sainte-Marie-Aux-Mines
Date d'inscription: 8 août 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 jeu. 15 décembre 2016 11:13

Ben22
Membre
Date d'inscription: 11 mai 2016
Messages: 12

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 (jeu. 15 décembre 2016 11:36)

Hors ligne

 

#7 jeu. 15 décembre 2016 11:37

legannec
Membre
Lieu: Sainte-Marie-Aux-Mines
Date d'inscription: 8 août 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

 

#8 jeu. 15 décembre 2016 12:26

jmarsac
Membre
Lieu: NICE
Date d'inscription: 26 oct. 2005
Messages: 212
Site web

Re: trigger : mise à jour d'une donnée entre deux tables

Envisager peut-être de redéfinir la variable [¡]search_path[/¡]


Jean-Marie

Hors ligne

 

Pied de page des forums

Powered by FluxBB

Partagez  |