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 Tue 15 December 2020 09:38

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Hiérachisation / conflits entre TRIGGER

Bonjour,

débutant avec les triggers j'ai beaucoup progressé grâce à l'aide des membres du forum que je remercie. cf post https://georezo.net/forum/viewtopic.php?id=121987 & https://georezo.net/forum/viewtopic.php?id=121953

Mais je suis encore confronté à un petit soucis qui je pense vient plus de l'organisation de la base de donnée voir de l'ordre de déclenchement des triggers plutôt que d'une erreur dans les triggers en soit. VOilà mon soucis :

J'ai 2 trigger.

Le TRIGGER 1 : remonte dans une table ligne une info "data" contenue dans une table point.

Le TRIGGER 2 : remonte dans la table ligne cette même info "data" pour toutes nouvelles lignes dont le point de départ correspond au point d'arrivée d'une ligne déjà existante.

L'idée derrière cela est de faire "suivre" l'info "data" de façon automatique lors du traçage de mes réseaux.


Quand je n'ai qu'un seul trigger "d'activé" ça fonctionne. Quand "j'active" les 2 triggers seul le TRIGGER 2 fonctionne, le TRIGGER 1 ne fonctionne plus.


TRIGGER 1

Code:

CREATE OR REPLACE FUNCTION TRIGGER 1 ()
RETURNS "trigger" AS $$
    BEGIN
        new.data= (SELECT p.data

FROM table_point as p


WHERE st_dwithin(st_startpoint(new.geom),(p.geom),0.001)
 );
        RETURN NEW;
    END;
$$
LANGUAGE 'plpgsql'VOLATILE;

CREATE TRIGGER TRIGGER 1
BEFORE INSERT OR UPDATE ON table_ligne
FOR EACH ROW EXECUTE PROCEDURE TRIGGER 1 ();

TRIGGER 2

Code:

CREATE OR REPLACE FUNCTION TRIGGER2 ()
RETURNS "trigger" AS $$
    BEGIN
        NEW.data=m.data 
        FROM table_ligne as m
WHERE st_dwithin(ST_startpoint(new.geom),st_endPoint(m.geom),0.001);
RETURN NEW;
    END;
$$
LANGUAGE 'plpgsql'VOLATILE;

CREATE TRIGGER TRIGGER2
BEFORE INSERT OR UPDATE ON table_ligne
FOR EACH ROW EXECUTE PROCEDURE TRIGGER2 ();

Existe t'il un moyen de les hiérarchiser ? ou de faire en sorte qu'ils ne se marchent pas sur les pieds ?

Merci de votre aide.

Vincent

Dernière modification par Vincent-SIABS (Tue 15 December 2020 10:01)

Hors ligne

 

#2 Tue 15 December 2020 09:43

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

Re: Hiérachisation / conflits entre TRIGGER

Bonjour,

les triggers se declenchent dans l'ordre alphabetique en cas de trigger sur la meme table.
Mais là, vous avez deux triggers sur la meme table, qui agissent sur la meme colonne: un peu bizarre: le dernier trigger qui va agir est celui qui va mettre la valeur a data.

vous voulez un seul trigger, avec eventuellement du code suivant le contexte pour faire des choses différentes.

Nicolas

Hors ligne

 

#3 Tue 15 December 2020 09:56

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: Hiérachisation / conflits entre TRIGGER

Merci de votre retour.

Plus j'y pense et plus j'ai l'impression qu'il faut regrouper en un seul TRIGGER avec des "conditions".

Du genre :

SI point de départ de ma table ligne = point de ma couche table_point
ALORS
data.table_ligne = data.table.point
SINON
SI point de départ de ma table ligne = point de fin d'une ligne existante dans ma_table_ligne
ALORS
new.data.table_ligne = old.data.table_ligne

J'ai "ça" dans la tête mais je bloque pour le transcrire en requête.

Je potasse la doc dispo sur Internet mais sans succès. :-/

Merci de votre aide.

Hors ligne

 

#4 Tue 15 December 2020 10:01

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

Re: Hiérachisation / conflits entre TRIGGER

Oui c'est cela qu'il faut faire.

La doc de PG sur PLPGSQL est plutot bien faite, avec des exemples de code: https://www.postgresql.org/docs/13/plpgsql.html

Nicolas

Hors ligne

 

#5 Tue 15 December 2020 11:22

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: Hiérachisation / conflits entre TRIGGER

Merci pour ce lien.

Je tente de transcrire avec mes connaissances et ça donne cela :

Code:

CREATE OR REPLACE FUNCTION monschema.TRIGGER3 ()
RETURNS "trigger" AS $$
    BEGIN
    IF st_dwithin(st_startpoint(new.geom),(p.geom),0.001) THEN new.data = p.data from table_point as p;
RETURN NEW;
    ELSEIF st_dwithin(ST_startpoint(new.geom),st_endPoint(m.geom),0.001) THEN new.data = m.data from table_ligne as m;
RETURN NEW;
    END IF;
    END;
    $$
LANGUAGE 'plpgsql'VOLATILE;

CREATE TRIGGER TRIGGER3
BEFORE INSERT OR UPDATE ON table_ligne
FOR EACH ROW EXECUTE PROCEDURE TRIGGER3 ();

J'espère que personne ne va faire une attaque en voyant ça car il y a surement de belles erreurs. Notament un qui me donne le message suivant :

Erreur PostGIS lors de l'ajout d'entité : ERREUR:  entrée manquante de la clause FROM pour la table « p »


Je ne comprends pas comment lui indiquer dans quelle table trouver les bons champs :-(

Merci pour l'énorme coups de pouce !

Dernière modification par Vincent-SIABS (Tue 15 December 2020 11:41)

Hors ligne

 

#6 Tue 15 December 2020 12:43

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

Re: Hiérachisation / conflits entre TRIGGER

Il y a plusieurs façons de faire, par exemple:

• chercher s'il y a un candidat proche dans la table_point
• si data est null, chercher s'il y a un candidat proche dans la table_ligne
• Sinon, aucun candidat et NEW.data sera null:

Code:

CREATE OR REPLACE FUNCTION monschema.TRIGGER3()
    RETURNS "trigger" AS
$$
BEGIN
    NEW.data := p.data
        from table_point as p
        where st_dwithin(st_startpoint(NEW.geom), (p.geom), 0.001);

    if NEW.data is null then
        NEW.data = m.data from table_ligne as m
        where st_dwithin(ST_startpoint(NEW.geom), st_endPoint(m.geom), 0.001);
    END IF;

    RETURN NEW;
END;
$$ LANGUAGE 'plpgsql' VOLATILE;

Vous pouvez inverser l'ordre des tests suivant la probabilité que NEW soit plutot proche d'un point ou d'une ligne (pour éviter de faire un calcul inutile)

(le code suppose que NEW.data est null en arrivant dans le trigger. A adapter si ce n'est pas le cas.)

(pensez a virer les anciens triggers de la table !)

Nicolas

Hors ligne

 

#7 Tue 15 December 2020 13:59

Vincent-SIABS
Participant actif
Date d'inscription: 20 Sep 2016
Messages: 57

Re: Hiérachisation / conflits entre TRIGGER

Bon 2 choses s'imposent :
1 - Un grand merci à vous !
2 - Remplir la demande de formation pour 2021 sur postgis et le sql ;-)

Encore merci !

Hors ligne

 

#8 Tue 15 December 2020 14:27

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

Re: Hiérachisation / conflits entre TRIGGER

Vincent-SIABS a écrit:

Bon 2 choses s'imposent :
1 - Un grand merci à vous !
2 - Remplir la demande de formation pour 2021 sur postgis et le sql ;-)

Encore merci !


Ouuiii, a votre disposition pour une formation postgis !

Hors ligne

 

Pied de page des forums

Powered by FluxBB