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 31/07/2015 16:31:01

LKIWI
Membre

fonction de mise à jour automatique (trigger)

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

#2 01/08/2015 17:29:06

rjuju
Administrateur

Re : fonction de mise à jour automatique (trigger)

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.

Hors ligne

#3 03/08/2015 18:57:19

dverite
Membre

Re : fonction de mise à jour automatique (trigger)

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.

Hors ligne

#4 06/08/2015 15:26:22

LKIWI
Membre

Re : fonction de mise à jour automatique (trigger)

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

#5 06/08/2015 16:16:15

MitsuTomoe
Membre

Re : fonction de mise à jour automatique (trigger)

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

#6 07/08/2015 10:23:01

LKIWI
Membre

Re : fonction de mise à jour automatique (trigger)

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 big_smile

Hors ligne

#7 07/08/2015 15:19:14

MitsuTomoe
Membre

Re : fonction de mise à jour automatique (trigger)

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

#8 11/08/2015 12:19:23

LKIWI
Membre

Re : fonction de mise à jour automatique (trigger)

ah effectivement c’était bien ça. Je vous remercie de vos reponses.
big_smile

Hors ligne

Pied de page des forums