Vous n'êtes pas identifié(e).
Pages : 1
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
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.
Julien.
https://rjuju.github.io/
Hors ligne
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
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.
Julien.
https://rjuju.github.io/
Hors ligne
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
Quelle erreur rencontrez-vous ? Votre procédure stockée est syntaxiquement correcte, ou est-ce à l'exécution que vous rencontrez un problème ?
Julien.
https://rjuju.github.io/
Hors ligne
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
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
ç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
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
Pages : 1