banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

#1 Fri 18 December 2015 15:06

VirginieV
Juste Inscrit !
Date d'inscription: 18 Dec 2015
Messages: 7

Trigger Update avec st_contains ou st_overlaps

Bonjour,

J'ai besoin d'aide car je débute avec les triggers sous PostGis.

J'ai 2 tables :
- voirie_communale (référentiel)
- voirie_diag

Lors de la création du diag, je peux copier la polyligne de mon référentiel pour redessiner mon diag, et je souhaite que des champs remontent automatiquement (id_voie et c_insee)

Le trigger suivant fonctionne avec la fonction qui suit :

CREATE CONSTRAINT TRIGGER insert_diag
  AFTER INSERT
  ON public.voirie_diag
  FOR EACH ROW
  EXECUTE PROCEDURE public.trig_insert_id_voie();

CREATE OR REPLACE FUNCTION public.trig_insert_id_voie()
  RETURNS trigger AS
$BODY$
BEGIN
    UPDATE voirie_diag SET
    id_voie = (SELECT voirie_communale.id_voie FROM voirie_communale WHERE voirie_communale.geom = voirie_diag.geom),
    c_insee = (SELECT voirie_communale.c_insee FROM voirie_communale WHERE voirie_communale.geom = voirie_diag.geom);
    RETURN NULL;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION public.trig_insert_id_voie()
  OWNER TO sdei36;

Toutefois, si je coupe mon diag pour avoir plusieurs diag sur une même voie, je perds évidemment les infos puisque je n'ai plus la même geom.

J'ai donc voulu modifier le select avec :

SELECT voirie_communale.id_voie FROM voirie_communale, voirie_diag WHERE ST_Contains (voirie_diag.geom, voirie_communale.geom) OR ST_Overlaps (voirie_diag.geom, voirie_communale.geom)

Cela fonctionne avec le select uniquement mais dès que je le passe sous un UPDATE, j'ai une erreur :

UPDATE voirie_diag SET id_voie =
(SELECT voirie_communale.id_voie FROM voirie_communale, voirie_diag WHERE ST_Contains (voirie_diag.geom, voirie_communale.geom) OR ST_Overlaps (voirie_diag.geom, voirie_communale.geom))
WHERE voirie_diag.id_voie is Null;

>>>>  ERREUR:  plus d'une ligne renvoyée par une sous-requête utilisée comme une expression

J'espère être claire. Merci d'avance pour votre aide car je suis bloquée.

Hors ligne

 

#2 Fri 18 December 2015 15:24

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1542

Re: Trigger Update avec st_contains ou st_overlaps

Bonjour,

Votre requete update n'est pas bonne.
La syntaxe est: UPDATE matable SET macolonne = valeur FROM dautrestables WHERE conditions;
(http://www.postgresql.org/docs/9.4/stat … pdate.html)

Dans votre cas: (j'ai ajouté des parenthèses autour du or spatial):

Code:

UPDATE voirie_diag  SET id_voie = voirie_communale.idvoie
FROM voirie_communale
WHERE (ST_Contains (voirie_diag.geom, voirie_communale.geom) OR ST_Overlaps (voirie_diag.geom, voirie_communale.geom)))
and voirie_diag.id_voie is Null;

Nicolas

Hors ligne

 

#3 Fri 18 December 2015 15:29

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1542

Re: Trigger Update avec st_contains ou st_overlaps

Vous devriez aussi corriger l'update de la fonction du trigger:

dans ce cas, l'update marche car le select renvoie bien une seule valeur pour la colonne, mais c'est un cas particulier.

Nicolas

Hors ligne

 

#4 Fri 18 December 2015 15:34

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1542

Re: Trigger Update avec st_contains ou st_overlaps

Quelque chose comme:

Code:

UPDATE voirie_diag SET
    id_voie = voirie_communale.id_voie,
    c_insee = voirie_communale.c_insee
FROM voirie_communale 
WHERE voirie_communale.geom = voirie_diag.geom

Attention avec cette clause where:
vous comparez les géometries avec l'opérateur "=": il ne compare que le bbox des géometries, pas les géometries elles-mêmes.
Il existe st_equals pour comparer deux géométries.

Nicolas

Hors ligne

 

#5 Fri 18 December 2015 15:47

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1542

Re: Trigger Update avec st_contains ou st_overlaps

En fait, je ne comprends pas bien ce que vous voulez faire avec ces triggers.

Qui lance l'insert qui déclenche le trigger ? qgis, du code SQL ?

Pourquoi vous n'inserez pas directement id_voie et c_insee dans commune_diag ?

Nicolas

Hors ligne

 

#6 Fri 18 December 2015 16:59

VirginieV
Juste Inscrit !
Date d'inscription: 18 Dec 2015
Messages: 7

Re: Trigger Update avec st_contains ou st_overlaps

Merci beaucoup ! Ça marche ! Il faut que je développe cela un peu plus, mais c'est un bon début.

En fait, depuis Qgis ou l'application web, je voulais que les champs soient repris automatiquement dans ma table diag sans ressaisie par l'utilisateurs. L'id_voie me sert ensuite de jointure pour récupérer les différents diag sur une même voie (coupures, historique) et le code insee pour les restrictions de visualisation, d'où le fait de créer un trigger déclenché par insert ou update d'un diag.

Nicolas Ribot a écrit:

Pourquoi vous n'inserez pas directement id_voie et c_insee dans commune_diag ?


Dans commune_diag ???
Y'a peut-être une meilleure solution à laquelle je n'aurais pas pensé ...

Virginie

Hors ligne

 

#7 Fri 18 December 2015 17:22

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1542

Re: Trigger Update avec st_contains ou st_overlaps

Ok, du coup, lorsque vous insérez les géométries issues de voirie_communale dans voirie_diag, vous insérez aussi id_voirie et c_insee.

Là, en l'état, ne gardez pas ce trigger en production !
A chaque insert, il lance un update complet de toute la table.

Nicolas

Hors ligne

 

#8 Mon 21 December 2015 09:13

VirginieV
Juste Inscrit !
Date d'inscription: 18 Dec 2015
Messages: 7

Re: Trigger Update avec st_contains ou st_overlaps

En fait, pour cela j'ai rajouté la condition si le champs est Null. Mais je pense qu'effectivement, l'update se fait sur toute la table. 

Je ne vois pas comment faire pour que cela s'applique que sur les nouveaux enregistrements.

Virginie

Hors ligne

 

Pied de page des forums

Powered by FluxBB