PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 07/10/2022 11:33:42

SebCham
Membre

Fonction déclencheur et utilisation de TG_TABLE_XXXX

Bonjour à tous et tous,

J'essaie sous Postgresql de créer une contrainte de vérification de la topologie d'objets insérés sur une table test.topo1 (pour empêcher la saisie sous QGIS d'objets se chevauchant).
Pour faire cela, j'ajoute un trigger sur cette table et je créé une fonction déclencheur. Ce qui donne ceci :

CREATE OR REPLACE FUNCTION admingeo.overlapping_parcel_trigger()
  RETURNS trigger AS
  $$
    DECLARE
      c bigint;
    BEGIN

      SELECT count(*)
      INTO c
      FROM test.topo1 t1
      WHERE ST_Intersects(t1.geom, NEW.geom)
      AND t1.id != NEW.id
      AND ST_Relate(t1.geom, NEW.geom, '2********');

      IF c > 0 THEN
        RAISE EXCEPTION 'l''objet % empiète sur un autre objet', NEW.id;
      END IF;

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


CREATE CONSTRAINT TRIGGER verif_topo
    AFTER INSERT OR UPDATE ON test.topo1
    FOR EACH ROW EXECUTE FUNCTION admingeo.overlapping_parcel_trigger();


Cette procédure fonctionne parfaitement mais je dois rentrer en dur le nom de la table sur lequel est posé mon trigger, ce qui n'est pas du tout optimal.
J'ai donc essayé d'introduire TG_TABLE_SCHEMA et TG_TABLE_NAME mais sans aucun succès après des dizaines de tentatives.
L'un de vous aurait-il une solution à mon problème svp ?
Merci d'avance pour votre aide.


Voici le code de ma dernière tentative :

CREATE or replace FUNCTION admingeo.overlapping_parcel_trigger()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
    DECLARE
      c bigint;   
      t1 text;
      
    BEGIN
                    
    EXECUTE format('select (schemaname::text||''.''||tablename::text)::regclass t from pg_tables where schemaname=%I and tablename=%I',TG_TABLE_SCHEMA,TG_TABLE_NAME) INTO t1;      
    
          
      SELECT Count(*)
      INTO c
      
      FROM t1
            
      WHERE ST_Intersects(t1.geom, NEW.geom)
      AND t1.id != NEW.id
      AND ST_overlaps(t1.geom, NEW.geom);

      IF c > 0 THEN
        RAISE EXCEPTION 'l''objet % empiète sur un autre objet', NEW.id;
      END IF;

      RETURN NEW;
    END;
  $BODY$;


Merci.

Hors ligne

#2 07/10/2022 12:59:07

rjuju
Administrateur

Re : Fonction déclencheur et utilisation de TG_TABLE_XXXX

Vous ne pouvez pas utiliser une chaine de texte pour remplacer un identifiant de table (ou autre), vous devez utiliser une requête dynamique pour ça.

Quelquechose comme


EXECUTE format('SELECT count(*) FROM %I.%I WHERE ST_Intersects...', TG_TABLE_SCHEMA, TG_TABLE_NAME) INTO c;

Hors ligne

#3 07/10/2022 14:33:42

SebCham
Membre

Re : Fonction déclencheur et utilisation de TG_TABLE_XXXX

Merci beaucoup pour votre aide smile
Je ne maîtrise pas du tout les requêtes dynamiques, désolé.

J'ai modifié ma requête ainsi :

(...)
EXECUTE format('SELECT count(*) FROM %I.%I as x
                    WHERE ST_Intersects(x.geom, NEW.geom)
                             AND x.id != NEW.id AND ST_overlaps(x.geom, NEW.geom)',                   
                    TG_TABLE_SCHEMA, TG_TABLE_NAME) INTO c;   
(...)


et j'obtiens ce message d'erreur dans QGIS :
" ERREUR:  entrée manquante de la clause FROM pour la table « new » "

Je suppose qu'il ne reconnait plus cette syntaxe à l'intérieur de la requête dynamique mais je ne sais pas comment désigner autrement la géométrie et l'id du dernier objet saisi...
Auriez-vous une idée ?

Merci d'avance pour votre aide.

Hors ligne

#4 07/10/2022 15:09:09

rjuju
Administrateur

Re : Fonction déclencheur et utilisation de TG_TABLE_XXXX

Vous devez fournir les valeurs NEW.id et autre explicitement :

EXECUTE format('SELECT count(*) FROM %I.%I WHERE ST_Intersects... AND x.id != $1 AND ...', TG_TABLE_SCHEMA, TG_TABLE_NAME) USING NEW.id INTO c; 

(idem pour geom, et tout autre valeur de NEW)

Voir https://www.postgresql.org/docs/current … CUTING-DYN pour plus de détails.

Hors ligne

#5 07/10/2022 15:57:05

SebCham
Membre

Re : Fonction déclencheur et utilisation de TG_TABLE_XXXX

Super, ca fonctionne parfaitement ! Merci beaucoup (je vous dois une fière chandelle). wink
Je vais enfin pouvoir créer des fonctions plus intelligentes et optimisées !
Bon week-end à vous

Hors ligne

#6 07/10/2022 17:09:50

rjuju
Administrateur

Re : Fonction déclencheur et utilisation de TG_TABLE_XXXX

Très bonne nouvelle, bon weekend également smile

Hors ligne

Pied de page des forums