Vous n'êtes pas identifié(e).
Pages : 1
Merci beaucoup pour votre aide.
Bonjour,
j'ai un problème sur un trigger que je perçois en partie.
Dans une table, j'ai une colonne ident avec une contrainte d'unicité. Pour créer cet ident, j'ai créée un trigger (BEFORE INSERT OR UPDATE) qui concatène 3 champs de trois autres colonnes (ident=concat(toto,'_',titi,'_',tata) : attention ce n'est pas mon code, c'est pour information).
Le problème est que quand je souhaite mettre à jour plusieurs lignes en même temps en ajoutant +1 au champ tata par exemple, j'ai un message d'erreur qui m'indique que la contrainte d'unicité est violée car un ident existe déjà. Ça me parait normal, car l'update se fait ligne par ligne et il rencontre forcément le même ident à un moment donné?
Y a t-il un moyen de contourner de celà?
Je peux détailler un peu plus avec du code par la suite si l'explication ne semble pas claire.
Merci
Bonjour,
voici ce que j'ai trouvé pour répondre à mon problème.
Après avoir copié toute les données depuis table_origine vers table_travail.
Je créée deux fonctions déclencheurs distinctes:
- une pour les insertions et les mise à jour dans table_origine
-- FUNCTION: schema.insert_update_on_table_travail()
-- DROP FUNCTION IF EXISTS schema.insert_update_on_table_travail();
CREATE OR REPLACE FUNCTION schema.insert_update_on_table_travail()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
IF (TG_OP = 'INSERT') THEN
INSERT INTO schema.table_travail ( value_1, value_2,...)
VALUES (new.value_1, new.value_2,…) ;
ELSEIF (TG_OP = 'UPDATE') THEN
UPDATE schema. table_travail
SET value_1 = new. value_1,
value_2 = new. value_2,
....
WHERE table_travail.identifiantunique=new.identifiantunique;
END IF;
RETURN NEW;
END
$BODY$;
- une pour les suppressions d'objets dans table_origine
-- FUNCTION: schema.delete_on_table_travail()
-- DROP FUNCTION IF EXISTS schema.delete_on_table_travail();
CREATE OR REPLACE FUNCTION schema.delete_on_table_travail()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
DELETE FROM schema.table_travail
WHERE table_travail.identifiantunique=old.identifiantunique;
RETURN OLD;
END
$BODY$;
J'applique ces deux délclencheurs à table_origine.
un lors des insertion et des mises à jour:
CREATE TRIGGER trigger_insert_update_on_table_travail
BEFORE INSERT OR UPDATE
ON schema.table_origine
FOR EACH ROW
EXECUTE FUNCTION trigger_insert_update_on_table_travail();
un lors de la suppression:
CREATE TRIGGER trigger_maj_delete_on_table_travail
AFTER DELETE
ON schema.table_origine
FOR EACH ROW
EXECUTE FUNCTION trigger_maj_delete_on_table_travail();
A présent, dès que j'agis dans ma de table_origine, table_travail est modifiée à l'identique sur les colonnes sélectionnées dans la fonction déclencheur (toute dans mon cas) et je peux créer des colonnes dans table_travail qui n'apparaitront pas dans table_origine.
Le sujet est donc résolu pour moi, mais je ne sais pas comment le clore.
Bonjour et merci pour votre retour,
J’ai regardé un peu du côté de l’héritage mais ça ne correspond pas au besoin je pense, même si c’est très intéressant pour ma culture.
Je vais essayer de simplifier :
- table_origine (table patrimoniale avec données géographiques (point) dans laquelle je ne souhaite pas ajouter d’autres colonnes pour le moment) = table_travail (avec les l’ensemble des ligne de la table_origine) --> copie des données dans une autre table ok pour moi
- table_travail doit se mettre à jour à chaque évènement qui a lieu sur la table_origine (insert / update / delete) --> ???
Au gré de demandes spécifiques, je pourrai ajouter des colonnes modifiables dans table_travail et garder ma table_origine « propre ».
J’espère que c’est plus clair…
Je ne sais pas si c'est il est possible de supprimer ou déplacer ma question, mais je viens de me rendre compte qu'elle aurait certainement du être placée dans le forum Général...
Bonjour à tous,
je suis relativement nouveau dans la gestion de base de donnée.
J'ai une base de données au travail (postgresql avec postgis administrée par pgAdmin 4) qui est polluée, à mon sens, à chaque demande particulière de la hiérarchie par la création d'une colonne. (Exemple de logique de mon collègue: demande --> faire remonter par nos équipes terrain toutes les poubelles de couleurs noires (donnée que nous n'avons pas) qui seront ensuite changées par des poubelles de couleur jaune / réponse--> création d'une colonne pb_noire avec oui / non en inscription) Je précise que c'est un exemple et que la colonne finira par ne plus servir.
Je ne suis pas sur que la réflexion soit idéale mais je souhaiterais créer une table "parallèle" (table_provisoire) à la table de base (table_origine) de manière à pouvoir y créer des colonnes "provisoires" et ne pas polluer l'originale. Il faudrait qu'à chaque fois qu'une entité est créée, modifiée ou supprimée dans table_origine, table_provisoire se mette à jour avec toutes les colonnes de table_origine sans condition (j'ai un identifiant unique dans ma table_origine qui s'incrémente). Peut-on passer par un trigger (que je n'arrive pas à créer...) ou autre?
J'espère que mon explication est assez claire.
Merci d'avance pour l'aide qui pourra m'être apportée!
Bonjour,
merci beaucoup pour votre réactivité! Ça ne tenait pas à grand chose...
Bonjour,
je suis nouveau et débutant en SIG.
Je souhaiterais concaténer 3 champs (insee,'_'ar_num,'_'lum_numero) d'une table afin de mettre à jour un quatrième champ (ident) de cette même table lorsque l'un des 3 premiers champs cité est modifié.
Je travaille avec PGAdmin.
Si j'ai bien compris, je dois créer une fonction générale que je pourrais éventuellement appliquer à plusieurs tables et ensuite j'applique un trigger sur la table concernée?
J'ai récupéré un exemple que j'ai modifié mais il doit y avoir une erreur dès le départ.
Fonction:
CREATE OR REPLACE FUNCTION nom_fonction()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
new.ident := concat(insee,'_',ar_numero,'_',lum_numero);
RETURN NEW;
END
$BODY$;
Trigger:
CREATE TRIGGER test
BEFORE INSERT OR UPDATE OF insee, ar_numero, lum_numero
ON schema.matable
FOR EACH ROW
EXECUTE FUNCTION nom_fonction();
Lorsque je modifie un des trois champs dans QGIS, j'ai un message d'erreur me disant que les colonnes sélectionnées n'existent pas:
Impossible de valider les changements pour la couche geo_ep_points_lumineux_plugin
Erreurs : ERREUR : 1 modification(s) de valeurs d'attribut n'ont pas été effectuée(s).
Erreur du fournisseur de données :
Erreur PostGIS lors de la modification d'attribut : ERROR: column "insee" does not exist
LINE 1: SELECT concat(insee,'_',ar_numero,'_',lum_numero)
^
QUERY: SELECT concat(insee,'_',ar_numero,'_',lum_numero)
CONTEXT: PL/pgSQL function nom_fonction() line 3 at assignment
Lorsque je ne renvoie pas à une colonne et uniquement à du texte dans la fonction, le trigger fonctionne et mon champ se remplie avec le texte concerné.
J'espère avoir été clair, et je vous remercie par avance de votre aide.
Pages : 1