Vous n'êtes pas identifié(e).
Bonjour,
Je simplifie la difficulté que je rencontre en prenant pour exemple une table nommée arret, comportant les colonnes suivantes arret_id (integer), arret_phase (integer), arret_poly_id (integer), arret_info (character)
Je souhaiterais qu'à l'ajout d'un enregistrement dans cette table un trigger se déclenche pour contrôler si il n'existe pas déjà des enregistrements avec la même valeur de arret_poly_id et le cas échéant qu'il remplisse le champ arret_info avec la valeur arret_info de l'enregistrement ayant la même valeur de arret_poly_id et la plus grande valeur de arret_phase.
Voilà ce que j'ai déjà codé :
CREATE OR REPLACE FUNCTION arret_insert_func()
RETURNS trigger AS
$BODY$BEGIN
IF new.arret_poly_id = arret_poly_id THEN
UPDATE arret SET(new.arret_phase, new.arret_info)
SELECT MAX( arret_phase )+1, arret_info
FROM arret
WHERE arret_poly_id = new.arret_poly_id
GROUP BY arret_poly_id, arret_phase, arret_info ;
END IF;
RETURN NEW;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION arreteinsert_func()
OWNER TO me;
CREATE TRIGGER arret_insert
AFTER INSERT
ON arret
FOR EACH ROW
EXECUTE PROCEDURE arret_insert_func();
Cette fonction renvoie une erreur, elle ne reconnait pas la colonne arret_poly_id. Je pense qu'il faudrait que j'utilise une boucle for mais je n'en ai jamais utilisée et suis un peu perdue du coup.
Pour être plus compréhensible voici un exemple:
arret_id arret_phase arret_poly_id arret_info
1 1 100 blabla
2 1 200 blublu
3 2 100 bloblo
4 1 300 blibli
Avec les valeurs suivantes, l'ajout d'un enregistrement ayant comme valeur arret_poly_id =100 complèterait les champs arret_info et arret_phase avec les valeurs respectives bloblo et 3.
En espérant trouver de l'aide,
Amélie
Hors ligne
Il faut en effet exécuter une boucle FOR du style :
FOR variable in SELECT ...
LOOP
END LOOP
Dans la boucle, il faut intégrer les modifications dans la ligne pointée par la variable NEW.
Guillaume.
Hors ligne
Bonjour,
Voici ce que j'ai mis en place. Je ne sais pas si c'est la meilleure solution mais en tout cas ça fonctionne :
CREATE OR REPLACE FUNCTION arret_insert_func()
RETURNS trigger AS
$BODY$
DECLARE
s RECORD ;
cur CURSOR FOR SELECT DISTINCT ON (arret_poly_id) arret_poly_id, arret_phase, arret_info
FROM arret
ORDER BY arret_poly_id, arret_phase DESC;
BEGIN
OPEN cur;
LOOP
FETCH NEXT FROM cur INTO s;
EXIT WHEN NOT FOUND;
IF new.arret_poly_id = s.arret_poly_id THEN
new.arret_info := s.arret_info ;
END IF;
END LOOP;
CLOSE cur;
RETURN new;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION domaine_public.arret_insert_func()
OWNER TO me;
CREATE TRIGGER arret_insert
BEFORE INSERT
ON arret
FOR EACH ROW
EXECUTE PROCEDURE arret_insert_func();
(A noter que le calcul du champs arret_phase s'effectue préalablement et n'est plus codé dans cette fonction)
Amélie
Dernière modification par amelo (08/11/2013 11:08:01)
Hors ligne
C'est l'idée, même si je l'aurais codé plutôt ainsi :
CREATE OR REPLACE FUNCTION arret_insert_func()
RETURNS trigger AS
$BODY$
DECLARE
p_arret_poly_id arret.arret_poly%TYPE;
p_arret_phase arret.arret_phase%TYPE;
p_arret_info arret.arret_info%TYPE;
BEGIN
FOR p_arret_poly_id, p_arret_phase, p_arret_info IN
SELECT DISTINCT ON (arret_poly_id) arret_poly_id, arret_phase, arret_info
FROM arret
ORDER BY arret_poly_id, arret_phase DESC
LOOP
IF new.arret_poly_id = p_arret_poly_id THEN
new.arret_info := p_arret_info ;
END IF;
END LOOP;
RETURN new;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Guillaume.
Hors ligne