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).

#26 17/02/2021 16:34:26

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#27 17/02/2021 17:03:28

dverite
Membre

Re : update concatenation champ + row_number

Dans un trigger AFTER INSERT il est trop tard pour modifier les données à insérer.
Il faut le faire dans un BEFORE INSERT.

Il faut voir aussi que si NEW.bv ou NEW.insee.com est  à NULL, le concaténer avec autre chose donnera NULL (appliquer la fonction coalesce() pour transformer d'abord les NULL en chaîne vide si le cas peut se présenter)

Dernière modification par dverite (17/02/2021 17:03:51)

Hors ligne

#28 17/02/2021 17:18:33

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#29 17/02/2021 18:09:37

gleu
Administrateur

Re : update concatenation champ + row_number

En soit, le code fourni fonctionne. Si vous ajoutez d'autres choses à l'ensemble, en effet, ça peut ne plus fonctionner. C'est compliqué de vous aider si vous ne nous donnez pas une idée complète du truc. Si je comprends bien, bv et insee_com ne sont pas renseignés dans le INSERT mais par le code de triggers. J'en reviens toujours à ma demande initiale : un code complet qui réflète tout votre problème, du CREATE SCHEMA au INSERT qui ne fonctionne pas comme vous le souhaitez.

Ce que je peux au moins dire, c'est que ces deux fonctions triggers sont fausses. Il serait bon de les modifier de la même façon que la première fonction trigger. De plus, avoir plusieurs fonctions triggers sur la même table pour la même action est un brin dangereux. Actuellement, les triggers sont lancés dans l'ordre du nom du trigger (ou de la fonction ? je ne sais plus)... ce qui fait qu'il est possible que, même avec un bon code, les fonctions se déclenchent dans un autre ordre, ce qui aboutira à un comportement différent.


Guillaume.

Hors ligne

#30 17/02/2021 18:34:55

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#31 17/02/2021 20:41:15

dverite
Membre

Re : update concatenation champ + row_number

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é  ?

C'est possible et cette cascade de triggers qui s'exécute dans le mauvais ordre semble techniquement la cause du problème de champ qui reste à NULL. Le BEFORE INSERT ne peut pas dépendre de résultats qui sont générés par le AFTER INSERT.
En trigger multiples, il faut que tous les triggers soit en BEFORE INSERT, qu'ils ne fassent pas d'UPDATE mais qu'ils utilisent tous NEW.champ = (valeur calculée) et que leur nommage soit dans l'ordre alphabétique de l'ordre de déclenchement voulu.

Mais cet édifice est compliqué et fragile à maintenir.

Vous pourriez peut-être pousser le raisonnement un cran plus loin et remettre en question le fait d'utiliser des triggers pour remplir ces colonnes. Pourquoi ne pas mettre directement les valeurs finales calculées dès l'INSERT?

Est-ce que le côté client est une interface utilisateur genre pgAdmin où l'utilisateur peut juste mettre des valeurs dans des cellules pour déclencher l'insertion et vous n'avez pas la maîtrise du SQL qui fait la clause INSERT?

Sinon une autre solution (si la motivation est d'isoler l'appelant des règles métier) est d'encapsuler l'INSERT dans une fonction plpgsql (appelée par SELECT) qui prend les paramètres les valeurs à insérer et qui calcule les valeurs générées via des calculs intermédiaires dans des variables, en mode procédural.

Hors ligne

#32 18/02/2021 09:35:18

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#33 18/02/2021 12:04:18

gleu
Administrateur

Re : update concatenation champ + row_number

Il y a un point qu'il faudra aussi vérifier. Dans les deux derniers triggers, vous avez un code ressemblant à ceci :

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);

Autrement dit, la colonne bv est mise à jour pour toutes les lignes de ouvrage_v4.n_ouvrage_protection_l_004_005. Est-ce vraiment cela que vous voulez faire ou voulez-vous plutôt mettre à jour la valeur du bv pour la ligne en cours de modification lors de l'exécution du trigger ?


Guillaume.

Hors ligne

#34 18/02/2021 12:40:46

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#35 18/02/2021 13:00:25

gleu
Administrateur

Re : update concatenation champ + row_number

Dans ce cas, il faudra remplacer comme précédemment avec quelque chose du type :

SELECT hydro_zone.code_zone::text INTO NEW.bv
FROM ouvrage_v4.hydro_zone
WHERE St_Intersects(hydro_zone.geom, NEW.geom)
LIMIT 1;

Ce qui donnerait une fonction trigger complète de ce type :

CREATE OR REPLACE FUNCTION ouvrage_v4.num_id_ouvrage()
RETURNS trigger
LANGUAGE plpgsql
AS
$BODY$
BEGIN
-- calcul du nouveau bv
SELECT hydro_zone.code_zone::text INTO NEW.bv
FROM ouvrage_v4.hydro_zone
WHERE St_Intersects(hydro_zone.geom, NEW.geom)
LIMIT 1;

-- calcul du nouveau insee_com
SELECT  commune.insee_com INTO NEW.insee_com
FROM   ouvrage_v4.commune
WHERE   St_Intersects(commune.geom, NEW.geom)
LIMIT 1;

-- calcul du nouveau id_ouvrage
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);

-- renvoi de la nouvelle ligne modifiee par nos soins
RETURN NEW;
END;
$BODY$;

Il y a certainement moyen de faire plus joli mais c'est ce à quoi j'arrive rapidement.


Guillaume.

Hors ligne

#36 18/02/2021 17:01:22

RémiChairat
Membre

Re : update concatenation champ + row_number

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 ?

Dernière modification par RémiChairat (18/02/2021 17:03:05)

Hors ligne

#37 18/02/2021 19:09:54

gleu
Administrateur

Re : update concatenation champ + row_number

Certains changent le titre du sujet, c'est à ma connaissance le seul moyen.


Guillaume.

Hors ligne

#38 18/01/2022 15:17:50

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#39 18/01/2022 16:55:51

rjuju
Administrateur

Re : update concatenation champ + row_number

Bonjour,


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.


Cela dit, je pense que votre approche est vouée à l'échec dans tous les cas.  En plus d'être probablement assez lent, cela ne pourra jamais garantir une valeur cohérente en cas d'insertion concurrente, ou tout simplement de mise à jour.


Pourquoi ne tout simplement pas utiliser une unique sequence, quelque soit le bn ou insee?  Sinon, le seul moyen pour garantir une unicité serait de créer une contrainte unique de cette colonne générée, et que votre applicatif essaye de réinsérer en boucle les données en cas de doublons jusqu'à ce que cela fonctionne.

Hors ligne

#40 18/01/2022 17:04:55

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#41 19/01/2022 05:04:57

rjuju
Administrateur

Re : update concatenation champ + row_number

Comment vous assurez-vous que les champs BV et INSEE sont immutables, ou qu'aucune ligne n'est jamais supprimée ?  Sans ces éléments vous avez la garantie d'avoir des données problématiques à terme, ce qui me laisse penser que l'approche que vous souhaitez n'est pas une bonne idée.


Si malgré tout vous voulez persister sur cette approche, vous pouvez préciser si votre trigger voit des valeurs nulles, comme indiqué dans mon précédent mail, afin de valider l'origine de votre problème.   Et idéalement créer une contrainte unique sur cette colonne, car cela sera le seul moyen de garantir l'unicité (ce qui est différent de garantir la validité des données).


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 present 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.

Hors ligne

#42 19/01/2022 08:58:50

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#43 19/01/2022 10:17:08

rjuju
Administrateur

Re : update concatenation champ + row_number

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.

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 ?


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.


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.


Sincèrement je ne vois pas comment on pourrait aider avec ces informations.  Le seul moyen serait que vous fournissiez une suite de commande SQL pour reproduire le problème de 0 à partir d'une base vide, donc avec tous les DDL et DML.  Et évidemment une version simplifiée serait mieux, par exemple pas besoin d'inclure postgis, juste une table qui contient le retour de la vraie jointure spatiale ou quelque chose du g enre.

Hors ligne

#44 19/01/2022 10:19:33

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#45 19/01/2022 10:28:29

RémiChairat
Membre

Re : update concatenation champ + row_number

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

Hors ligne

#46 19/01/2022 11:55:58

rjuju
Administrateur

Re : update concatenation champ + row_number

Effectivement vu que mon champ BV n’était pas rempli pour les ouvrages déjà existant


C'est un très clair signe qu'il vous manque un ou plusieurs NOT NULL dans votre schéma.


mais effectivement en cas d'erreur de positionnement le mieux sera de supprimer l'objet et de repositionner celui ci
[...]
il était convenu avec les utilisateurs de la bases que aucun ouvrage ne doit être supprimer


À priori cela n'est pas compatible ?

Hors ligne

#47 19/01/2022 12:06:41

RémiChairat
Membre

Re : update concatenation champ + row_number

À 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

Hors ligne

Pied de page des forums