Vous n'êtes pas identifié(e).
Pages : 1
je viens une fois de plus sur ce forum pour exposer un problème auquel je suis confronté. Je suis stagiaire dans une collectivité et une partie de mon sujet de stage est la mise à jour automatique d'une nouvelle base adresse que je viens de créer. Mes tables sont toutes remplies de la façon suivante:
create table donnees_adresse
(idu_adresse integer primary key,ADRESSE_concat varchar (255),code_rivoli integer not null, num_voie char (7), iter_voie char (10), type_voie varchar(15),nom_voie varchar (255), parcelle_de_rattachmt varchar(255), code_iris interger not null, entree_principal char (3), entree_reference varchar(255), coord_X float, coord_Y float,
geom GEOMETRY);
insert into donnees_adresse (geom) select "Cadastre".geo_adresse.geom from "Cadastre".geo_adresse
update....idu_adresse........set = where =
update..ADRESSE_concat....set = where = ;
update....code_rivoli.......set = case when substr() like .... then substr () else '' end;
etc......
et je veux une ou des fonction(s) trigger(s) qui pourront faire :
- le 1er insert
-ensuite, declancher tous les nombreux update à la chaine
PS: Toutes les tables de ma base de données sont remplies de la même manière
Je suis perdu avec tout ce qui se dit sur le net concernant les fonctions "trigger" et leur utilisation.
HELP ME PLEASE
Hors ligne
Bonjour,
Je n'ai absolument rien compris à votre problème. Je vous conseille de lire http://docs.postgresql.fr/9.4/plpgsql-trigger.html et http://docs.postgresql.fr/9.4/sql-createtrigger.html puis de revenir si vous avez un problème concret à résoudre.
Julien.
https://rjuju.github.io/
Hors ligne
Je suis perdu avec tout ce qui se dit sur le net concernant les fonctions "trigger" et leur utilisation.
Oubliez les triggers si vous êtes débutant.
La confusion consiste à partir du principe qu'un trigger serait nécessaire pour faire des opérations basiques.
Ne faites ni fonction ni trigger.
Il y a besoin de créer une nouvelle ligne? Faites un INSERT.
Il y a besoin de mettre à jour une ligne existante? Faites un UPDATE.
Un seul UPDATE permet de mettre à jour plusieurs colonnes de la même ligne.
@DanielVerite
http://blog-postgresql.verite.pro/
Hors ligne
Bonjour,
merci Rjuju pour la doc. En fait j'ai une table de métadonnées associés à mes tables, je voudrais une fonction qui se déclenche et qui renseigne automatiquement la dernière date de mise à jour dans une des colonne de la table de metadonnees:
-lorsqu'on lance un insert
-lorsqu'on lance un update
(vu que le remplissage de ma table s'est fait colonne par colonne).
CREATE OR REPLACE FUNCTION date_mise_a_jour() RETURNS TRIGGER AS $$
BEGIN
-- Insertion date de dernière mise à jour
NEW.date_maj = now();
update bas_adresse_localisation.metadonnees set date_maj = New.now() ;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER date_maj after INSERT OR UPDATE ON base_adresse_localisation.metadonnees
FOR EACH ROW EXECUTE PROCEDURE date_mise_a_jour();
Malheureusement mon code n'est pas juste donc il se passe rien dans la colonne date_maj
Merci
Hors ligne
Bonjour,
je ne suis pas certain d'avoir bien compris ce que vous voulez faire . Avez-vous 2 tables bas_adresse... et base_adresse... ou est-ce une faute de frappe ?
En tout cas, pour mettre la date de derniere mise à jour il faut utiliser le signe d'affectation := et non pas le comparateur = .
Pour l'update, si vous ne mettez pas de clause where toute la table sera mise à jour. NEW.now() ne veut rien dire, utilisez simplement now(), il ne change pas pendant la durée de la transaction.
Un exemple simple qui marche :
CREATE FUNCTION stamp_update() RETURNS trigger
LANGUAGE plpgsql
AS $$DECLARE
nom_base varchar;
BEGIN
SELECT INTO nom_base current_database();
NEW.dat_tran := current_timestamp;
NEW.user_db_tran := nom_base;
RETURN NEW;
END;$$;
CREATE TRIGGER stamp_update BEFORE INSERT ON adresse FOR EACH ROW EXECUTE PROCEDURE stamp_update();
Je ne sais pas à quoi correspond votre table de métadonnées, mais dans un projet précédent j'avais une table d'archivage par table "utilisateur" de toutes les opérations effectuées alimentée automatiquement de cette façon (exemple tables adresse et adresse_log):
CREATE FUNCTION log_adresse() RETURNS trigger
LANGUAGE plpgsql
AS $$BEGIN
IF (TG_OP = 'DELETE' ) THEN
INSERT INTO adresse_log SELECT 'D', now(), OLD.*;
RETURN OLD;
ELSEIF (TG_OP = 'UPDATE' ) THEN
INSERT INTO adresse_log SELECT 'U', now(), NEW.*;
RETURN NEW;
ELSEIF (TG_OP = 'INSERT' ) THEN
INSERT INTO adresse_log SELECT 'I', now(), NEW.*;
RETURN NEW;
END IF;
RETURN NULL; END;$$;
CREATE TRIGGER xlog_adresse BEFORE INSERT OR DELETE OR UPDATE ON adresse FOR EACH ROW EXECUTE PROCEDURE log_adresse();
Les 2 tables ont la meme structure , a part un champ code transaction et un timestamp en plus pour la table log.
J'espère que ces exemples vous aideront.
Alex
Hors ligne
merci de ta réponse MitsuTomoe, je crois bien qu'on se rapproche de la solution. J'essaierai d'expliquer mieux ce que j'attends de la fonction en question. en faite j'ai une table adresse avec différentes colonnes, et chaque colonne est mise à jour grâce à un script sql (type update nom_colonne set num_voie= ...........). et moi j'aimerais qu'à chaque requête lancer sur un champ: qu'il me mettent la date de mise à jour de la colonne dans une autre table de metadonnée.
voici comment se présente ma table adresse
num_voie | iter_voie | libellé_voie |
________________________________
27 | bis | rue de la Mairie |
13 | | rue de Belfort |
et voici ma table métadonnées
libel_colonne | description_colonne | sources_donnees | licence_usage | date_maj |
___________________________________________________________________________
num_voie | numero de la voie |sources |......................| |
iter_voie | iteration de la voie |sources |......................| |
libellé_voie | libellé de la voie |sources |......................| |
merci d'avance de votre aide
Hors ligne
J'imagine que la table metadonnees a une clef primaire avec sources_donnees, libel_colonne ? Est-ce que sources_donnees est un nom de table ?
Si c'est bien ca, il faut faire une jointure adresse --> metadonnees .
Dans un trigger , le nom de la table est dans TG_TABLE_NAME .
Pour savoir quels sont les champs modifiés, il faut comparer OLD et NEW;
Exemple :
IF (NEW.num_voie != OLD.num_voie) THEN
UPDATE metadonnees SET date_maj = now() WHERE (sources_donnees=TG_TABLE_NAME AND libel_colonne='num_voie')
END IF;
... idem pour tous les champs...
RETURN NEW
Courage ! PostgreSQL est un super outil, on peut tout faire. Essayez de bien structurer vos questions, on a parfois du mal a vous comprendre.
Alex
Hors ligne
ah effectivement c’était bien ça. Je vous remercie de vos reponses.
Hors ligne
Pages : 1