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 17/04/2013 11:12:00

grandyoz
Membre

[Résolu] Création d'un trigger SQL

Bonjour,

Je ne connais pas du tout les trigger et je me noie un peu !

J'ai une table TABLE1 (id, champ1, champ2) et une autre TABLE2(id,table1_id,champ1,champ2)

Je souhaite qu'à chaque fois qu'un enregistrement est inséré ou modifié dans TABLE2 que l'enregistrement lié de la TABLE1 soit mis à jour de telle sorte que TABLE1.champ1 (where TABLE1.id = TABLE2.table1_id de l'enregistrement en cours) = (somme de TABLE2.champ1 WHERE TABLE2.table1_id = TABLE2.table1_id de l'enregistrement en cours)

Pouvez-vous m'aider ?

En vous remerciant,

AG

Dernière modification par grandyoz (22/04/2013 17:04:23)

Hors ligne

#2 17/04/2013 12:23:49

rjuju
Administrateur

Re : [Résolu] Création d'un trigger SQL

Bonjour,

un tel trigger est possible, mais en général il est préférable d'avoir cette information en utilisant une vue, plutôt que de maintenir un champ calculé à jour.

De plus, il faudrait également gérer un trigger sur la suppression.

Hors ligne

#3 17/04/2013 13:13:24

grandyoz
Membre

Re : [Résolu] Création d'un trigger SQL

Bonjour,
Merci pour l'info.
Les données de la table 2 ne peuvent pas être supprimées. Seulement ajoutées ou modifiées.
Pour les vues, c'est vrai que c'est une idée, mais un peu compliquée à mettre en oeuvre dans mon context actuel.

Pourriez-vous me donner des pistes sur la structure du trigger à créer ?

En vous remerciant

Hors ligne

#4 17/04/2013 13:32:04

rjuju
Administrateur

Re : [Résolu] Création d'un trigger SQL

La documentation donne toutes les informations : http://docs.postgresql.fr/9.2/plpgsql-trigger.html

Vous devrez créer une fonction avec un type de retour « trigger », et créer un trigger sur la table qui appelle cette fonction.

Hors ligne

#5 17/04/2013 14:14:09

grandyoz
Membre

Re : [Résolu] Création d'un trigger SQL

oui, j'ai vu... mais je ne m'en sors pas !
Mais bon, c'est pas grave, je vais faire autrement.
Merci quand même pour l'aide.

Hors ligne

#6 17/04/2013 14:24:13

rjuju
Administrateur

Re : [Résolu] Création d'un trigger SQL

Quelle erreur rencontrez-vous ? Votre procédure stockée est syntaxiquement correcte, ou est-ce à l'exécution que vous rencontrez un problème ?

Hors ligne

#7 17/04/2013 14:54:24

grandyoz
Membre

Re : [Résolu] Création d'un trigger SQL

En fait, je n'ai rien, je ne suis pas du tout à l'aise avec la syntaxe car je ne la connais pas et je me base sur les docs et exemples.

Je vais regarder ce que je peux faire de plus.

A+

Hors ligne

#8 18/04/2013 12:59:12

MitsuTomoe
Membre

Re : [Résolu] Création d'un trigger SQL

Un exemple réel vous aidera probablement. J'ai écrit ce code alors que je découvrais PG, il est donc certainement perfectible,
mais ça fonctionne.

Le trigger :

CREATE TRIGGER agenda_projet BEFORE INSERT OR UPDATE ON client_projet FOR EACH ROW EXECUTE PROCEDURE agenda_projet();

La fonction :

CREATE FUNCTION agenda_projet() RETURNS trigger
    LANGUAGE plpgsql
    AS $$--
--        A partir de l'insertion ou update dans PROJET, on met à jour les agendas du projet, du licencié, de son équipe, et des acquéreurs concernés.
--

DECLARE
vtypact integer;
vlic record;
vident record;
vdesc varchar;
vlib varchar;
vevent integer;
vtrt integer;
vidlic integer;
videquipe integer;
vmandat record;
vgroupe record;
vmandatvendeur record;
vdatfin date;
vinit varchar;

BEGIN

    vtrt := 0;
    CASE
        WHEN  (TG_OP = 'INSERT') THEN
            vtrt := 1;

        WHEN (TG_OP = 'UPDATE') THEN
            vtrt := 2;
    END CASE; 
   
    
    SELECT INTO vgroupe * FROM GROUPE_CLIENT WHERE  id_groupe=NEW.id_groupe;
     IF NOT FOUND THEN
         RAISE EXCEPTION 'Aucun acquéreur trouvé pour le projet %',NEW.id_groupe;
         RETURN NULL;
     END IF;

    vidlic := NEW.nego_in;
        IF (vidlic IS NULL) THEN
            RAISE EXCEPTION 'Aucun licencié trouvé pour le projet %',NEW.id_projet;
            RETURN NULL;
        END IF;

     SELECT INTO vlic * FROM LICENCIE WHERE id_licencie=vidlic;
     IF NOT FOUND THEN
         RAISE EXCEPTION 'Le licencié % n''existe pas !', vidlic;
         RETURN NULL;
     END IF;        
     
     SELECT INTO videquipe id_equipe FROM LICENCIE_PERIODE WHERE (((id_licencie = vidlic) AND (dat_debut <= current_date)) AND ((dat_fin >= current_date OR dat_fin IS NULL)));
     IF NOT FOUND THEN
         RAISE EXCEPTION 'L''équipe n''a pas été trouvée pour le licencié %',vidlic;
         RETURN NULL;
     END IF;
     
     SELECT INTO vident * FROM IDENTITE where id_identite=vlic.id_identite;
     IF NOT FOUND THEN
         RAISE EXCEPTION 'Pas d''identité pour le licencié % !', vidlic;
         RETURN NULL;
     END IF;        
           
     CASE
         WHEN (vtrt = 1) THEN
             IF (NEW.mandat_rech IS TRUE) THEN
                 vlib := 'Mandat de recherche ';
             ELSE
                 vlib := 'Mandat simple ';
             END IF;
             vdesc:=vlib||'no. '||NEW.id_projet;

         WHEN (vtrt = 2) THEN
                 IF (NEW.typ_etat_projet != OLD.typ_etat_projet) THEN
                     SELECT INTO vlib lib_long FROM LISTE_CHOIX WHERE (cd_lang = 'fr' AND no_liste=10 AND no_val=NEW.typ_etat_projet);
                     vdesc:= 'projet '||NEW.id_projet||'  '||vlib;
                 ELSE
                     RETURN NEW;
                 END IF;
       
     END CASE;
     IF (NEW.dat_lim IS NULL) THEN
         vdatfin := NEW.dat_projet + interval '1 year';
     ELSE
         vdatfin := NEW.dat_lim;
    END IF;

     vtypact := 19;
    
     INSERT INTO AGENDA VALUES(default,1,vtypact,vdesc,NEW.dat_projet,vdatfin) RETURNING currval('agenda_id_event_seq') into vevent;
     RAISE NOTICE 'Création de l''évènement % dans l''agenda',vevent;

     INSERT INTO CLIENT_PROJET_AGENDA VALUES(NEW.id_projet,vevent);
     RAISE NOTICE 'Création de l''évènement % dans l''agenda du client % projet %',vevent,NEW.id_groupe,NEW.id_projet;

     INSERT INTO LICENCIE_AGENDA VALUES(vidlic,vevent);
     RAISE NOTICE 'Création de l''évènement % dans l''agenda du licencié %',vevent,vidlic;

     INSERT INTO EQUIPE_AGENDA VALUES(videquipe,vevent);
     RAISE NOTICE 'Création de l''évènement % dans l''agenda de l''équipe %',vevent,videquipe;

  

     RETURN NEW;
    
END;$$;


ALTER FUNCTION public.agenda_projet() OWNER TO conclavi;

Hors ligne

#9 18/04/2013 13:25:53

grandyoz
Membre

Re : [Résolu] Création d'un trigger SQL

ça c'est super sympa ! Je pense que ça va me mettre sur la bonne piste ! Merci beaucoup, c'est cool.
Si j'y arrive, je posterai mon résultat pour les suivants !
A+

Hors ligne

#10 22/04/2013 17:04:06

grandyoz
Membre

Re : [Résolu] Création d'un trigger SQL

Chose promise, chose due !

Voilà finalement mon trigger ! Tout simple, mais quand on connait pas...

Merci beaucoup pour votre aide.

CREATE FUNCTION update_fct() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
DECLARE
nb_item bigint;
nb_credits bigint;
BEGIN
    SELECT INTO nb_item COUNT(*) FROM xxx WHERE xxx = NEW.id;
    SELECT INTO nb_credits SUM(credits) FROM yyyy WHERE zzz = NEW.id;
    UPDATE ddd SET nb_items=nb_item,credits=nb_credits,modified=NOW() WHERE id = NEW.id;
    RETURN NULL;
END;$$;
CREATE TRIGGER update_fct AFTER INSERT OR UPDATE ON xxx FOR EACH ROW EXECUTE PROCEDURE update_fct();

Hors ligne

Pied de page des forums