#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: 1554
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: 1554
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: 1554
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: 1554
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.
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: 1554
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