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 Re : PL/pgSQL » update concatenation champ + row_number » 19/01/2022 12:06:41

À priori cela n'est pas compatible ?

Non mais si il y aune erreur flagrante de positionnement alors oui l'administrateur reprendra le positionnement si celui-ci est juste décalé de quelque mètres il ne devrait pas modifier son id_ouvrage vu qu'il sera toujours dans le périmètre de la commune et du Bassin versant, par contre dans le cas ou l'objet est vraiment mal placé ni sur le bon périmètre de commune ni sur le bon bv en supprimer l'objet et en recréant un objet la numérotation devrait ce refaire proprement sans créé de conflit.

Quand je parle de ne pas supprimer d'objet je parle d'objet qui sont bien placé et bien numéroté mais qui ne serais juste plus en activité ce qui effectivement risquerai de provoquer des souci car si l'ouvrage 1 est supprimer alors que nous en somme a l'ouvrage 40 sur ce secteur il va y avoir un décalage qui vas embêter pour l'avenir.

Rémi

#2 Re : PL/pgSQL » update concatenation champ + row_number » 19/01/2022 10:28:29

Re Bonjour Julien,

Le problème avec "ça ne peut pas arriver donc pas besoin d'ajouter un controle" est qu'en général ça finit quand même par arriver.  Je ne connais pas le cas d'utilisation, mais par exemple que se passe-t-il si un ouvrage change de position ?  Ou si vous vous rendez compte une fois l'importation faite que le GPS avait un problème et que la position était incorrecte ?

les ouvrages en question sont les digues et enrochement ou grillage anti éboulement etc... ce ne sont pas des ouvrages qui sont amené a ce déplacer mais effectivement en cas d'erreur de positionnement le mieux sera de supprimer l'objet et de repositionner celui ci sur la carte afin d’éviter des troues dans la numérotations.

effectivement un objet peut être supprimé  et cela pause effectivement un souci dans la numérotation.

Comment comptez-vous résoudre ce problème ?  À priori tant que vous n'avez pas de solution je ne suis pas sûr qu'il soit intéressant d'essayer de corriger les autres problèmes.

Pour cela il était convenu avec les utilisateurs de la bases que aucun ouvrage ne doit être supprimer un historique doit etre conservé afin d'avoir un suivi sur l’ensemble des ouvrages ceux qui sont actif et ceux qui ne le sont pas pour cela un autre champ de la table permet de déterminer si l'ouvrage est actif ou non.
donc normalement même un ouvrage non actif ne pourra être supprimé .

Rémi

#3 Re : PL/pgSQL » update concatenation champ + row_number » 19/01/2022 10:19:33

Re Bonjour
Je viens de corriger une partie du Problème en effet le champ BV de ma base de données n’était pas rempli pour les anciens objet déjà existant dans la base c'est pour cela que ma numérotation fonctionné uniquement sur les nouveaux objet créé depuis que j'ai fait cet update de ma table la numérotation  fonctionne et prends effectivement en compte les précédent objet et commence donc la numérotation à la suite des précédent objet.

ET grâce a cela je viens de comprendre ton premier message julien ou tu disait :

James a écrit :

Je ne suis pas certain de comprendre votre problème.  Le count() devrait prendre un compte le nombre d'éléments?  Sauf si une ou les deux valeurs sont NULL.

Effectivement vu que mon champ BV n’était pas rempli pour les ouvrages déjà existant il ne pouvait pas dire qu'elles étaient les ouvrages ayant les même bv et insee

Désolé julien pour ma mauvaise compréhension de ton premier message.

Rémi

#4 Re : PL/pgSQL » update concatenation champ + row_number » 19/01/2022 08:58:50

Bonjour Julien,

Pour le fait que BV et INSEE sont immutables c'est le cas étant données qu'ils sont récupéré par une jointure spatiale c'est en effet la position de l'objet qui vas définir ce code bv et le code insee donc eux ne pourront pas changer. effectivement un objet peut être supprimé  et cela pause effectivement un souci dans la numérotation.

Pour palier a cette problématique est il possible de rajouter une fonction à la suite de ma concaténation BV_INSEE qui rendrai celle ci absolument unique car en effet je pensé qu'il était plus simple de faire une incrémentation de 1 en 1 mais effectivement à la vu de ce problème je réalise que ce n'est pas forcement la meilleur solution.

De plus, vous dites "en effet pour le moment l’incrémentation démarre a 1 quelque soit le nombre d'ouvrage ayant le même bv_insee présent dans la base".  Comment l'incrémentation peut "démarrer à 1" et ensuite fonctionner comme vous le souhaitez?  Dans les deux cas cela dépend du nombre d'enregistrements déjà présents.

je suis le premier surpris mais je viens de refaire le test sur une zone ou il existe déjà des ouvrages et je viens de créer 2 nouveaux objet et le premier objet a pris la valeur 1 et le deuxième la valeur 2 (je ne sais pas comment vous envoyer une capture d'écran sur le forum), c'est cela qui me fait penser que ma numérotation fonctionne bien sauf qu'il ne prend pas en compte les objets déjà enregistré.

extrait de la base de données :

id_ouvrage    id_origine    source
V531_05088_2    15-26-3-690    CD05
V531_05088_1    15-26-3-658    CD05
V531_05088_3    15-26-6-896    CD05
V531_05088_4    15-26-7-000    CD05
V531_05088_5    15-26-7-115    CD05
V531_05088_1        test1
V531_05088_2        test2

les deux ouvrages ajoutés sont ceux ayant comme id_origine test1 et test2 et comme vous pourrez le constater la numérotation s'incrémente correctement avec 1 et 2 mais viens en doublon avec les ouvrages existant.


Rémi

#5 Re : PL/pgSQL » update concatenation champ + row_number » 18/01/2022 17:04:55

Bonjour Julien,

pour comprendre la problématique il faut reprendre l'assemble des échanges ma base de données est une base des ouvrages de protection est je souhaite lorsque un ouvrage de protection est ajouté que l'identifiant qui la caractérise soit soit composé de la maniere suivante :

BV (code bassin versant)_ insee(code insee de la commune sur lequel ce trouve l'ouvrage)_ et une incrémentation simple de 1 en 1 en gros l'id ouvrage prend la forme suivante :

V531_05088_1 et si un autre ouvrage est créé dans le même bv et dans la même commune je souhaiterai que de manière automatique il prennent le valeur V531_05088_2 et ainsi de suite.
Le temps de calcul actuel n'est pas long et permet un remplissage des champs automatique et rapide par contre effectivement il ne prends pas en compte les ouvrages déjà existant.

Je cherche une solution pour répondre a cette problématique peut être que au niveau du SELECT(count(*)+1) qui fonctionne bien il faudrait rajouter un select distinct avec le bv et l'insee je ne sais pas si cela est possible ??

Cordialement,

Rémi

#6 Re : PL/pgSQL » update concatenation champ + row_number » 18/01/2022 15:17:50

Bonjour,

C'est à nouveau moi et malheureusement, je viens de constater que le fonction ma provoqué pas mal de souci notamment en ne prenant pas en compte les enregistrement déjà existant je m'explique la fonction fonctionne bien et me fourni bien des identifiants de type bv_insee_numérotation mais comme il n'a pas pris en compte les enregistrements précédents je me retrouve avec des doublons

-- calcul du nouveau id_ouvrage
NEW.id_ouvrage = NEW.bv||'_'||NEW.insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v4.ouvrage_protection WHERE bv=NEW.bv and insee=NEW.insee);

n'y a t'il pas moyen de rajouter une fonction qui lui indique qu'il doit compter le nombre de fois ou une concaténation 'bv_insee' est présente dans la base.

en effet pour le moment l’incrémentation démarre a 1 quelque soit le nombre d'ouvrage ayant le même bv_insee present dans la base.

Cordialement,

Rémi Chairat

#7 Re : PL/pgSQL » update concatenation champ + row_number » 18/02/2021 17:01:22

un immense merci guillaume et dverit vous avez trouvés la solution !!!

effectivement de mettre a jour une seul ligne a la fois et le regroupement dans un seul trigger en BEFORE a résolu le souci.

Rémi

PS : comment puis je basculer le sujet en fini sur le forum ?

#8 Re : PL/pgSQL » update concatenation champ + row_number » 18/02/2021 12:40:46

bonjour guillaume,

effectivement je ne veux mettre a jour que la ligne qui vient d'être ajouter car toutes les autres sont déjà complétés.

Rémi

#9 Re : PL/pgSQL » update concatenation champ + row_number » 18/02/2021 09:35:18

Bonjour dverite,

merci pour tes retours

Je pense que quelque info supplémentaire sont indispensable afin de comprendre le pourquoi de cette demande.

Cette base a pour objectif d’être utilisé dans lizmap afin de pouvoir mettre a disposition des gestionnaire d'ouvrage un outil leur permettant d'ajouter des éléments et de pouvoir suivre en temps réel leurs ouvrages.
le problème étant que le publique concerné par cet webcarto n'est pas géomaticien et donc une simplification du remplissage de la base est indispensable afin d'éviter tout erreur de saisie notamment au niveau de l'id_ouvrage.

je vais essayer de modifier tous mes triggers de AFTER à BEFORE pour voir si le résultat évolue.

je vous tiens au courant.

Rémi

#10 Re : PL/pgSQL » update concatenation champ + row_number » 17/02/2021 18:34:55

Bonjour guillaume,

En soit je ne rajoute rien je vous avez déja expliqué dans mes posts précédents que le champ insee_com et bv etaient issus de deux autres table qui sont la table commune et la table hydro_zone :

table commune :

CREATE TABLE ouvrage_v4.commune
(
  id integer NOT NULL DEFAULT nextval('ouvrage_v4."COMMUNE_id_seq"'::regclass),
  geom geometry(MultiPolygon,2154),
  insee_com character varying(5),
  nom_com character varying(50),
  insee_dep character varying(3),
  code_epci character varying(9),
  nom_com_m character varying(50),
  CONSTRAINT "COMMUNE_pkey" PRIMARY KEY ()
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ouvrage_v4.commune
  OWNER TO webcarto_w;

-- Index: ouvrage_v4."sidx_COMMUNE_geom"

-- DROP INDEX ouvrage_v4."sidx_COMMUNE_geom";

CREATE INDEX "sidx_COMMUNE_geom"
  ON ouvrage_v4.commune
  USING gist
  ();

table hydro_zone

CREATE TABLE ouvrage_v4.hydro_zone
(
  id integer NOT NULL DEFAULT nextval('ouvrage_v4."HYDRO_ZONE_id_seq"'::regclass),
  geom geometry(MultiPolygon,2154),
  code_zone character varying(4),
  libelle character varying(125),
  pkhexut bigint,
  id_bdcarth bigint,
  code_hydro character varying(8),
  libelle_so character varying(125),
  libelle_se character varying(125),
  libelle_re character varying(125),
  CONSTRAINT "HYDRO_ZONE_pkey" PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ouvrage_v4.hydro_zone
  OWNER TO webcarto_w;

-- Index: ouvrage_v4."sidx_HYDRO_ZONE_geom"

-- DROP INDEX ouvrage_v4."sidx_HYDRO_ZONE_geom";

CREATE INDEX "sidx_HYDRO_ZONE_geom"
  ON ouvrage_v4.hydro_zone
  USING gist
  (geom);

puis enfin ma table ouvrage de protection

CREATE TABLE ouvrage_v4.n_ouvrage_protection_l_004_005
(
  id integer NOT NULL DEFAULT nextval('ouvrage_v4."N_OUVRAGE_PROTECTION_L_004_005_id_seq"'::regclass),
  geom geometry(MultiLineString,2154),
  id_ouvrage character varying(254),
  nom_ouv character varying(254),
  date_maj date,
  source character varying(254),
  type_prtc character varying(254),
  materiaux character varying(254),
  obs_tech character varying(254),
  id_siouh character varying(254),
  id_bardig character varying(254),
  riviere character varying(254),
  code_frdr character varying(254),
  rive character varying(254),
  insee character varying(254),
  commune character varying(254),
  multi_com character varying(254),
  haut_ouv numeric,
  long_ouv numeric,
  propriete character varying(254),
  gestion character varying(254),
  affouill character varying(254),
  etat_struc character varying(254),
  vites_evol character varying(254),
  necs_inter character varying(254),
  propo_trvx character varying(254),
  an_inter character varying(254),
  dispo_prot character varying(254),
  syst_endig character varying(254),
  id_disptif character varying(254),
  nb_hab character varying(254),
  diag character varying(254),
  etude_dang character varying(254),
  arrete_cla character varying(254),
  ce_r214_1 character varying(254),
  document character varying(254),
  photo character varying(254),
  id_rtm character varying(50),
  bv character varying(20),
  epci character varying(100),
  group_users character varying(30),
  insee_com character varying(6),
  CONSTRAINT "N_OUVRAGE_PROTECTION_L_004_005_pkey" PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ouvrage_v4.n_ouvrage_protection_l_004_005
  OWNER TO webcarto_w;

-- Index: ouvrage_v4."sidx_N_OUVRAGE_PROTECTION_L_004_005_geom"

-- DROP INDEX ouvrage_v4."sidx_N_OUVRAGE_PROTECTION_L_004_005_geom";

CREATE INDEX "sidx_N_OUVRAGE_PROTECTION_L_004_005_geom"
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  USING gist
  (geom);

a partir de ces trois tables j'utilise les tables hydro_zone et commune pour compléter les champs bv et insee_com de la table ouvrage de protection
grace au trigger suivant

trigger bv

CREATE OR REPLACE FUNCTION ouvrage_v4.bv_ouvrage()
  RETURNS trigger AS
$BODY$BEGIN
update ouvrage_v4.n_ouvrage_protection_l_004_005
SET bv = (SELECT hydro_zone.code_zone::text
            FROM ouvrage_v4.hydro_zone
            WHERE St_Intersects(hydro_zone.geom, n_ouvrage_protection_l_004_005.geom)LIMIT 1);
return NEW; 
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v4.bv_ouvrage()
  OWNER TO webcarto_w;

CREATE TRIGGER a_bv_ouvrage
  AFTER INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.bv_ouvrage();

et trigger insee

CREATE OR REPLACE FUNCTION ouvrage_v4.insee_ouvrage()
  RETURNS trigger AS
$BODY$BEGIN
update ouvrage_v4.n_ouvrage_protection_l_004_005
SET insee_com =
           (SELECT  commune.insee_com
            FROM   ouvrage_v4.commune
            WHERE   St_Intersects(commune.geom, n_ouvrage_protection_l_004_005.geom)LIMIT 1) ;
return new; 
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v4.insee_ouvrage()
  OWNER TO webcarto_w;

CREATE TRIGGER b_insee_ouvrage
  AFTER INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.insee_ouvrage();

pour le coup ces deux triggers fonctionne parfaitement et à chaque ajout de ligne, automatiquement, les champs insee_com et bv de la table n_ouvrage_protection_l_004_005 s’ auto complète.

par contre le problème persiste pour ce qui concerne le champ id_desserte de la table n_ouvrage_protection_l_004_005 qui lui devrait s'auto completer grace au triggers suivant :

CREATE OR REPLACE FUNCTION ouvrage_v4.num_id_ouvrage()
  RETURNS trigger AS
$BODY$
BEGIN
NEW.id_ouvrage = NEW.bv||'_'||NEW.insee_com||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v4.n_ouvrage_protection_l_004_005 WHERE bv=NEW.bv and insee_com=NEW.insee_com);
RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v4.num_id_ouvrage()
  OWNER TO webcarto_w;
  
  CREATE TRIGGER e_num_id_ouvrage
  BEFORE INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.num_id_ouvrage();

en effet je souhaiterai comme expliqué dans mes posts précédent  que l'id_ouvrage soit composer de : 'bv'_'insee_com'_'numerotation pour éviter les doublons'
et actuellement tous mes trigger fonctionne sauf le dernier qui créer l'id_ouvrage qui lui ne me renvoi aucun message d'erreur mais juste il me laisse le champ vide.

d'après mes recherches sur la doc postgres les trigger s'enclenche dans l'ordre alphabétique c'est pour cela que j'ai nommé mes triggers :

a_bv_ouvrage
b_insee_ouvrage
e_num_id_ouvrage

afin d’éviter effectivement que le champ id_ouvrage soit calculé avant que mes champs insee_com et bv ne soit complété.

bref je continu mes recherches

PS : est-il possible d'enclencher un seul trigger qui procéderai à l’ensembles de ces étapes en une fois afin d’être sur que le champ id_ouvrage est bien calculé une fois que les autre champ sont complété  ?

Rémi

#11 Re : PL/pgSQL » update concatenation champ + row_number » 17/02/2021 17:18:33

Bonjour dverite,

J'ai procédé à la modification de mon trigger en mettant BEFORE INSERT  :

CREATE TRIGGER e_num_id_ouvrage
  BEFORE INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.num_id_ouvrage();

Malheureusement le problème reste le même pas de message d'erreur mais le champ reste null alors que les champ insee_com et bv sont complété de maniere automatique grace à deux triggers qui s'active en AFTER INSERT :

bv

CREATE OR REPLACE FUNCTION ouvrage_v4.bv_ouvrage()
  RETURNS trigger AS
$BODY$BEGIN
update ouvrage_v4.n_ouvrage_protection_l_004_005
SET bv = (SELECT hydro_zone.code_zone::text
            FROM ouvrage_v4.hydro_zone
            WHERE St_Intersects(hydro_zone.geom, n_ouvrage_protection_l_004_005.geom)LIMIT 1);
return NEW; 
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v4.bv_ouvrage()
  OWNER TO webcarto_w;

CREATE TRIGGER a_bv_ouvrage
  AFTER INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.bv_ouvrage();

et insee_com

CREATE OR REPLACE FUNCTION ouvrage_v4.insee_ouvrage()
  RETURNS trigger AS
$BODY$BEGIN
update ouvrage_v4.n_ouvrage_protection_l_004_005
SET insee_com =
           (SELECT  commune.insee_com
            FROM   ouvrage_v4.commune
            WHERE   St_Intersects(commune.geom, n_ouvrage_protection_l_004_005.geom)LIMIT 1) ;
return new; 
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v4.insee_ouvrage()
  OWNER TO webcarto_w;

CREATE TRIGGER b_insee_ouvrage
  AFTER INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.insee_ouvrage();

Rémi

#12 Re : PL/pgSQL » update concatenation champ + row_number » 17/02/2021 16:34:26

Bonjour Guillaume,

Le problème persiste aucun message d'erreur mais la colonne ne se rempli pas.

Donc le problème persiste,

J'ai simplifier ma base pour ne travailler que sur une table des ouvrages :

-- Table: ouvrage_v4.n_ouvrage_protection_l_004_005

-- DROP TABLE ouvrage_v4.n_ouvrage_protection_l_004_005;

CREATE TABLE ouvrage_v4.n_ouvrage_protection_l_004_005
(
  id integer NOT NULL DEFAULT nextval('ouvrage_v4."N_OUVRAGE_PROTECTION_L_004_005_id_seq"'::regclass),
  geom geometry(MultiLineString,2154),
  id_ouvrage character varying(254),
  nom_ouv character varying(254),
  date_maj date,
  source character varying(254),
  type_prtc character varying(254),
  materiaux character varying(254),
  obs_tech character varying(254),
  id_siouh character varying(254),
  id_bardig character varying(254),
  riviere character varying(254),
  code_frdr character varying(254),
  rive character varying(254),
  insee character varying(254),
  commune character varying(254),
  multi_com character varying(254),
  haut_ouv numeric,
  long_ouv numeric,
  propriete character varying(254),
  gestion character varying(254),
  affouill character varying(254),
  etat_struc character varying(254),
  vites_evol character varying(254),
  necs_inter character varying(254),
  propo_trvx character varying(254),
  an_inter character varying(254),
  dispo_prot character varying(254),
  syst_endig character varying(254),
  id_disptif character varying(254),
  nb_hab character varying(254),
  diag character varying(254),
  etude_dang character varying(254),
  arrete_cla character varying(254),
  ce_r214_1 character varying(254),
  document character varying(254),
  photo character varying(254),
  id_rtm character varying(50),
  bv character varying(20),
  epci character varying(100),
  group_users character varying(30),
  insee_com character varying(6),
  CONSTRAINT "N_OUVRAGE_PROTECTION_L_004_005_pkey" PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ouvrage_v4.n_ouvrage_protection_l_004_005
  OWNER TO webcarto_w;

-- Index: ouvrage_v4."sidx_N_OUVRAGE_PROTECTION_L_004_005_geom"

-- DROP INDEX ouvrage_v4."sidx_N_OUVRAGE_PROTECTION_L_004_005_geom";

CREATE INDEX "sidx_N_OUVRAGE_PROTECTION_L_004_005_geom"
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  USING gist
  (geom);

et ma function/trigger est la suivante :

function

CREATE OR REPLACE FUNCTION ouvrage_v4.num_id_ouvrage()
  RETURNS trigger AS
$BODY$
BEGIN
NEW.id_ouvrage = NEW.bv||'_'||NEW.insee_com||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v4.n_ouvrage_protection_l_004_005 WHERE bv=NEW.bv and insee_com=NEW.insee_com);
RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v4.num_id_ouvrage()
  OWNER TO webcarto_w;

trigger

CREATE TRIGGER e_num_id_ouvrage
  AFTER INSERT
  ON ouvrage_v4.n_ouvrage_protection_l_004_005
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v4.num_id_ouvrage();

et a mon grand regret mon champ id_ouvrage ne se complète pas ....


Rémi

#13 Re : PL/pgSQL » update concatenation champ + row_number » 16/02/2021 11:52:14

bonjour,

je suis désolé mais je bataille depuis mon dernier message et je ne voit toujours pas de solution personnes n'a une idée ???

Bonne journée,

Rémi

#14 Re : PL/pgSQL » update concatenation champ + row_number » 07/01/2021 16:24:18

dverite a écrit :

Cette fonction et ce trigger ne me renvoi aucun message d'erreur mais le champ 'id_ouvrage' de la table 'ouv_protec_epci_ca_dracenoise' ne se rempli pas.

Votre trigger en message #17 fait ça:

NEW.id_ouvrage = NEW.bv||'_'||NEW.insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise WHERE bv=NEW.bv and insee=NEW.insee and id_ouvrage=NEW.id_ouvrage);

La partie

and id_ouvrage=NEW.id_ouvrage

n'a pas de sens puisqu'elle cherche une valeur qui n'est pas encore remplie. Regardez bien ce qu'a proposé Guillaume en #11, il n'y avait pas cette condition.

effectivement erreur de ma part je corriges

#15 Re : PL/pgSQL » update concatenation champ + row_number » 07/01/2021 14:47:45

gleu a écrit :

Ah, j'oubliais aussi que la table ouvrage_v3.hydro_zone est déclarée avec une colonne bv, mais que le INSERT se fait sur une colonne insee. Il faut tester son jeu de tests pour s'assurer que tout sera reproductible.

oui pardon en voulant simplifier je me suis trompé dans mon copié coller il faut utiliser les creats envoyé dans le dernier message

#16 Re : PL/pgSQL » update concatenation champ + row_number » 07/01/2021 14:45:09

pardon je ne voulais encombré les exemple avec des creation de table complet et très lourd voici les script des deux tables :

table commune :

CREATE TABLE ouvrage_v3.commune
(
  gid serial NOT NULL,
  id character varying(24),
  prec_plani double precision,
  nom character varying(45),
  code_insee character varying(5),
  statut character varying(22),
  arrondisst character varying(45),
  depart character varying(30),
  region character varying(35),
  popul integer,
  geom geometry(MultiPolygon),
  CONSTRAINT commune_pkey PRIMARY KEY (gid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ouvrage_v3.commune
  OWNER TO webcarto_w;

-- Index: ouvrage_v3.commune_geom_idx

-- DROP INDEX ouvrage_v3.commune_geom_idx;

CREATE INDEX commune_geom_idx
  ON ouvrage_v3.commune
  USING gist
  (geom);

table hydro_zone :

CREATE TABLE ouvrage_v3.hydro_zone
(
  gid serial NOT NULL,
  code_zone character varying(4),
  libelle character varying(125),
  pkhexut numeric(10,0),
  id_bdcarth numeric(10,0),
  code_hydro character varying(8),
  libelle_so character varying(125),
  libelle_se character varying(125),
  libelle_re character varying(125),
  geom geometry(MultiPolygon),
  CONSTRAINT hydro_zone_pkey PRIMARY KEY (gid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE ouvrage_v3.hydro_zone
  OWNER TO webcarto_w;

-- Index: ouvrage_v3.hydro_zone_geom_idx

-- DROP INDEX ouvrage_v3.hydro_zone_geom_idx;

CREATE INDEX hydro_zone_geom_idx
  ON ouvrage_v3.hydro_zone
  USING gist
  (geom);

pour le remplissage des champs et notamment le champ geom je me retrouve face a une succession  de caractère très très longue je pense que je risque de saturer complétement la page du forum avec cette longue chaine de caractère.
si vous le souhaitez je vous envoi les couches en question afin que vous puissiez reproduire la création de base avec postgresql / postgis

Cordialement,

Rémi

#17 Re : PL/pgSQL » update concatenation champ + row_number » 07/01/2021 12:08:06

re Bonjour,

Je vais essayer d'etre le plus clair possible avec de nombreux exemple car j'ai oublié de parler de pas mal de points qui me semblaient pas utile car tout fonctionner mais je pense que cela doit avoir un lien avec mon problème final.

mon schema ouvrage_v3 est composé de trois tables :

        - ouv_protec_epci_ca_dracenoise (couche linéaire)
        - commune (couche surfacique)
        - hydro_zone (couche surfacique)

 
CREATE TABLE ouvrage_v3.communes (insee text, geom);
INSERT INTO ouvrage_v3.communes (insee) VALUES ('83044');
INSERT INTO ouvrage_v3.communes (insee) VALUES ('83013');

CREATE TABLE ouvrage_v3.hydro_zone (bv text, geom);
INSERT INTO ouvrage_v3.hydro_zone (insee) VALUES ('X230');
INSERT INTO ouvrage_v3.hydro_zones (insee) VALUES ('X240');

ces 2 tables vont me permettre grâce a deux trigger précédemment créés d'aller prendre les codes insee et bv utilisés dans la table  "ouvrage_v3.ouv_protec_epci_ca_dracenoise"

trigger et fonction pour le bv :

CREATE OR REPLACE FUNCTION ouvrage_v3.bv_ca_dracenoise()
  RETURNS trigger AS
$BODY$BEGIN
update ouvrage_v3.ouv_protec_epci_ca_dracenoise
SET     bv =
           (SELECT  hydro_zone.code_zone::text
            FROM   ouvrage_v3.hydro_zone
            WHERE   St_Intersects(hydro_zone.geom, ouv_protec_epci_ca_dracenoise.geom)) ;
return NEW; 
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v3.bv_ca_dracenoise()
  OWNER TO webcarto_w;

CREATE TRIGGER a_bv_dracenoise
  AFTER INSERT
  ON ouvrage_v3.ouv_protec_epci_ca_dracenoise
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v3.bv_ca_dracenoise();

trigger et fonction pour le code insee :

CREATE OR REPLACE FUNCTION ouvrage_v3.insee_ca_dracenoise()
  RETURNS trigger AS
$BODY$BEGIN
update ouvrage_v3.ouv_protec_epci_ca_dracenoise
SET  insee =
           (SELECT  commune.code_insee
            FROM   ouvrage_v3.commune
            WHERE   St_Intersects(commune.geom, ouv_protec_epci_ca_dracenoise.geom)) ;
return new; 
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v3.insee_ca_dracenoise()
  OWNER TO webcarto_w;


CREATE TRIGGER b_insee_dracenoise
  AFTER INSERT
  ON ouvrage_v3.ouv_protec_epci_ca_dracenoise
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v3.insee_ca_dracenoise();

ces deux trigger fonctionne parfaitement j'ai à chaque ajout d'ouvrage le code insee et le code bv qui sont automatiquement rempli dans les champs correspondant de la table ouv_protec_epci_ca_dracenoise

mais le dernier trigger et fonction sur lequel nous avons discuter jusqu’à maintenant :

CREATE OR REPLACE FUNCTION ouvrage_v3.id_ouvrage_ca_dracenoise()
  RETURNS trigger AS
$BODY$
BEGIN
NEW.id_ouvrage = NEW.bv||'_'||NEW.insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise WHERE bv=NEW.bv and insee=NEW.insee and id_ouvrage=NEW.id_ouvrage);
RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION ouvrage_v3.id_ouvrage_ca_dracenoise()
  OWNER TO postgres;

CREATE TRIGGER c_ca_dracenoise
  AFTER INSERT
  ON ouvrage_v3.ouv_protec_epci_ca_dracenoise
  FOR EACH ROW
  EXECUTE PROCEDURE ouvrage_v3.id_ouvrage_ca_dracenoise();

Cette fonction et ce trigger ne me renvoi aucun message d'erreur mais le champ 'id_ouvrage' de la table 'ouv_protec_epci_ca_dracenoise' ne se rempli pas.

pour info j'ai essayé de mettre un exemple de geom à rajouter au table commune et hydro_zone mais je me suis retrouvé avec une séquence de caractère de 100 lignes.

Voilà je pense avoir était le plus clair possible j’espère vous avoir données suffisamment d'informations si il y a un manque ne pas hésiter à me prévenir

merci d'avance pour vos retours

Rémi

#18 Re : PL/pgSQL » update concatenation champ + row_number » 06/01/2021 12:48:00

Re bonjour gleu et encore merci pour votre retour,

Cependant je rencontre encore un dernier problème en effet cela ne fonctionne pas, mon champ id_ouvrage reste vide a l'ajout d'une ligne. et je pense que le problème vient du fait que mon champ id_ouvrage a déjà été complété manuellement jusqu'à maintenant.

donc en gros ma table sans ajout de base est identique à la table suivante que vous avez créé dans le post précédent (cette table est une table que j'ai récupéré existante et jusqu’à maintenant remplie manuellement)   :

┌──────┬───────┬──────────────┐
│  bv  │ insee │  id_ouvrage  │
├──────┼───────┼──────────────┤
│ X230 │ 83044 │ X230_83044_1 │
│ X230 │ 83044 │ X230_83044_2 │
│ X240 │ 83013 │ X240_83013_1 │
│ X241 │ 83044 │ X241_83044_1 │
│ X241 │ 83044 │ X241_83044_2 │
│ X241 │ 83044 │ X241_83044_3 │
└──────┴───────┴──────────────┘

et c'est a partir de cette table que je souhaiterai que à chaque ajout l’incrémentation ce continue.

j’espère que mes explications sont clair ???

en gros dans l'exemple de votre post précédent il faudrait commencer par créer la table avec les valeurs déjà à l’intérieur

 
CREATE SCHEMA ouvrage_v3;
CREATE TABLE ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv text, insee text, id_ouvrage text);
INSERT INTO ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv, insee, id_ouvrage) VALUES ('X230', '83044', 'X230_83044_1');
INSERT INTO ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv, insee, id_ouvrage) VALUES ('X230', '83044', 'X230_83044_2');
INSERT INTO ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv, insee, id_ouvrage) VALUES ('X240', '83013', 'X240_83013_1');
INSERT INTO ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv, insee, id_ouvrage) VALUES ('X241', '83044', 'X241_83044_1');
INSERT INTO ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv, insee, id_ouvrage) VALUES ('X241', '83044','X241_83044_2');
INSERT INTO ouvrage_v3.ouv_protec_epci_ca_dracenoise (bv, insee, id_ouvrage) VALUES ('X241', '83044','X241_83044_3');
SELECT * FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise;

qui correspond à ma table de base que j'ai récupéré et a partir de cette table je souhaiterai que à chaque ajout la numérotation ce poursuive
ce qui n'est pas le cas actuellement.

cordialement,

Rémi

#19 Re : PL/pgSQL » update concatenation champ + row_number » 05/01/2021 17:56:15

re Bonjour et merci pour votre réponse,

Juste pour info je ne comprends pas ce que vous attendez comme exemple complet un export de ma base ?

cordialement,

Rémi

#20 Re : PL/pgSQL » update concatenation champ + row_number » 05/01/2021 16:53:08

Re Bonjour,

après quelques essai je rencontre à nouveau un probléme avec ma fonction :

 CREATE OR REPLACE FUNCTION ouvrage_v3.id_ouvrage_ca_dracenoise() RETURNS TRIGGER AS
$BODY$BEGIN
update ouvrage_v3.ouv_protec_epci_ca_dracenoise
SET     id_ouvrage = bv||'_'||insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise WHERE bv=NEW.bv and insee=NEW.insee);

END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100; 
ALTER FUNCTION ouvrage_v3.id_ouvrage_ca_dracenoise()
OWNER TO webcarto_w;

et le problème viens après ajout d'un élément j'ai un message qui apparait :

Erreurs de commit:
              ERREUR : 1 attribut non-ajouté.
             
            Erreur du fournisseur de données :
                  Erreur PostGIS lors de l'ajout d'entité : ERROR:  stack depth limit exceeded
                HINT:  Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.
                CONTEXT:  SQL statement "update ouvrage_v3.ouv_protec_epci_ca_dracenoise
                SET     id_ouvrage = bv||'_'||insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise WHERE bv=NEW.bv and insee=NEW.insee)"
                PL/pgSQL function ouvrage_v3.id_ouvrage_ca_dracenoise() line 2 at SQL statement
                SQL statement "update ouvrage_v3.ouv_protec_epci_ca_dracenoise
                SET     id_ouvrage = bv||'_'||insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise WHERE bv=NEW.bv and insee=NEW.insee)"
                PL/pgSQL function ouvrage_v3.id_ouvrage_ca_dracenoise() line 2 at SQL statement
                SQL statement "update ouvrage_v3.ouv_protec_epci_ca_dracenoise
                SET     id_ouvrage = bv||'_'||insee||'_'||(SELECT(count(*)+1)::text FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise WHERE bv=NEW.bv and insee=NEW.insee)"
                PL/pgSQL function ouvrage_v3.id_ouvrage_ca_dracenoise() line 2 at SQL statement
                SQL statement "update ouvrage_v3.ouv_protec_epci_ca_dracenoise
               
               etc etc etc etc etc .......

donc visiblement il tourne en rond quand le trigger ce declanche ..

je ne comprend pas pourquoi et comment eviter qu'il lance en rond la fonction ?

merci d'avance pour votre aide.

#21 Re : PL/pgSQL » update concatenation champ + row_number » 04/01/2021 10:14:50

bonjour merci pour l'indication je comprends mieux j'ai cru que valeur représenté une valeur
bref

#22 Re : PL/pgSQL » update concatenation champ + row_number » 04/01/2021 09:25:14

bonjour et bonne année,

Effectivement cette solution répond à mon problème la fonction count est bel et bien ce que je cherche, par contre je ne comprends pas exactement le into 'valeur' à quoi correspond ce valeur ?

merci pour votre retour

#23 Re : PL/pgSQL » update concatenation champ + row_number » 31/12/2020 10:52:30

effectivement je n'ai pas du être très clair dans mes explications.

en gros je dispose d'une table avec un champ id_ouvrage ce champ id_ouvrage est composé de la concaténation du champ bassin-versant (bv) du champ code_insee (insee) et j'aimerai afin que celui-ci soit unique et sans doublon pouvoir numéroté les ouvrages ayant un bv et un insee identique afin de les rendre unique.

voila un exemple :
BV_INSEE
X230_83044

et dans de nombreux cas les ouvrages sont disposé sur les mêmes bv et insee donc je me retrouve avec des bv_insee identique

X230_83044
X230_83044
X230_83044

pour remédier à cela j'aimerai pouvoir ajouté une numérotation pour tous les ouvrages qui s'incrémente automatiquement a chaque ajout

X230_83044_1
X230_83044_2
X230_83044_3
X240_83013_1
X241_83044_1
X241_83044_2
X241_83044_3

voila le résultat que j'aimerai obtenir donc dans ma fonction j'ai déjà la concaténation qui ce fait de manière automatique mais j'aimerai rajouter la numérotation automatique d’où le row_number avec PARTITION BY bv, insee afin qu'il recommence la numérotation à chaque changement de bv ou de insee.

j’espère avoir été plus clair cette fois-ci ?

Merci d'avance pour vos retours

#24 Re : PL/pgSQL » update concatenation champ + row_number » 30/12/2020 15:34:25

Bonjour Guillaume,

Merci pour ton retour, j'essaye de comprendre ta solution mais j'ai l'impression que la fonction count va compter le nombre de valeur égale ? dans mon cas je ne cherche pas à les compter mais à les distinguer a les rendre uniques une numérotation en plus du code bassin versant et du code insee me permet d'avoir des valeurs unique ?

je ne suis pas sur de comprendre votre proposition ?

#25 PL/pgSQL » update concatenation champ + row_number » 30/12/2020 12:29:40

RémiChairat
Réponses : 46

Bonjour,

je dispose d'une table d'ouvrage de protection, et je souhaite créer grâce à un trigger et une fonction un remplissage automatique du champ id_ouvrage en concaténant le champ bassin versant (bv) , code insee (insee)  , et j'aimerai ajouter a la fin un row_number qui permettra de distingué chaque ouvrage qui sont présent dans un même BV et insee.

Voici la fonction créé :

CREATE OR REPLACE FUNCTION ouvrage_v3.id_ouvrage_ca_dracenoise() RETURNS TRIGGER AS
$BODY$BEGIN
update ouvrage_v3.ouv_protec_epci_ca_dracenoise
SET     id_ouvrage = bv||'_'||insee||'_'||row_number
FROM (SELECT ROW_NUMBER() OVER (
		PARTITION BY bv, insee)
		FROM ouvrage_v3.ouv_protec_epci_ca_dracenoise
		) AS row_number;
return new; 
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100; 
ALTER FUNCTION ouvrage_v3.id_ouvrage_ca_dracenoise()
OWNER TO webcarto_w;

le résultat de cette requête ne me convient pas car l’incrémentation ne ce fait pas en effet j'ai toujours un résultat de type bv_insee_1.

Merci par avance pour vos réponses 

Rémi

Pied de page des forums

Propulsé par FluxBB