Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#1 28/03/2018 17:39:40
- bruhnil
- Membre
Impossible de supprimer une entité avec un trigger
Bonjour,
Je dois mettre à jour une table dashboard.t_suivi à partir de la table coordination.numerisation.
CREATE OR REPLACE FUNCTION update_t_suivi() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO dashboard.t_suivi (
id_coord,
lot,
cdd,
mission_moe,
id_prog,
id_nro,
numero,
insee,
com_dep,
statut,
emprise,
nom,
travaux,
longueur,
debut_trvx,
prog_dsp,
moa,
commentair,
envoi_moe
)
VALUES(
new.id_opp,
new.lot,
new.cdd,
new.phase,
new.id_prog,
new.id_nro,
new.numero,
new.insee,
new.com_dep,
new.statut,
new.emprise,
new.nom,
new.travaux,
new.longueur,
new.debut_trvx,
new.prog_dsp,
new.moa,
new.commentair,
new.envoi_moe)
;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
DROP TRIGGER IF EXISTS trg_update_t_suivi ON coordination.numerisation;
CREATE TRIGGER trg_update_t_suivi
BEFORE INSERT OR DELETE OR UPDATE ON coordination.numerisation
FOR EACH ROW
EXECUTE PROCEDURE update_t_suivi();
Lorsque je fais le test d'insérer une nouvelle entité dans la table coordination.numerisation, la ligne est bien automatiquement reportée dans la table dashboard.t_suivi, mais dès que je veux supprimer cette entité test dans la table numerisation, je reçois un message d’erreur : Impossible de valider les changements pour la couche Numérisation
Erreurs : ERREUR : 1 attribut non effacé.
Erreur du fournisseur de données :
Erreur PostGIS lors de la suppression d'entité : ERREUR: l'enregistrement « new » n'est pas encore affectée
DETAIL: La structure de ligne d'un enregistrement pas encore affecté est indéterminée.
Pourriez vous me dire ce qui cloche dans mon ma requete?
Merci d'avance!
Hors ligne
#2 28/03/2018 17:44:30
- gleu
- Administrateur
Re : Impossible de supprimer une entité avec un trigger
Vous utilisez un trigger BEFORE, donc il est déclenché avant la réalisation de l'opération, donc la variable NEW ne contient aucune information. Vous devez utiliser un trigger AFTER. Voir https://www.postgresql.org/docs/10/stat … anges.html.
Guillaume.
Hors ligne
#3 29/03/2018 11:28:29
- bruhnil
- Membre
Re : Impossible de supprimer une entité avec un trigger
Merci gleu pour la réponse,
J'ai modifié le trigger avec un AFTER et j'arrive bien cette fois à supprimer l'entité rajoutée dans la table coordination.numerisation mais la ligne apparait toujours dans la table dashboard.t_suivi.
La c
DROP TRIGGER IF EXISTS trg_update_t_suivi ON dashboard.t_suivi;
DROP TRIGGER IF EXISTS trg_update_t_suivi ON coordination.numerisation;
CREATE TRIGGER trg_update_t_suivi
AFTER UPDATE ON coordination.numerisation
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE update_t_suivi();
et si je rajoute les conditions DELETE et INSERT
DROP TRIGGER IF EXISTS trg_update_t_suivi ON dashboard.t_suivi;
DROP TRIGGER IF EXISTS trg_update_t_suivi ON coordination.numerisation;
CREATE TRIGGER trg_update_t_suivi
AFTER INSERT OR DELETE OR UPDATE ON coordination.numerisation
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE update_t_suivi();
je reçois cette erreur:
ERROR: ERREUR: la condition WHEN du trigger INSERT ne peut pas référencer les valeurs OLD
LINE 6: WHEN (OLD.* IS DISTINCT FROM NEW.*)
Hors ligne
#4 29/03/2018 14:18:51
- gleu
- Administrateur
Re : Impossible de supprimer une entité avec un trigger
J'ai modifié le trigger avec un AFTER et j'arrive bien cette fois à supprimer l'entité rajoutée dans la table coordination.numerisation mais la ligne apparait toujours dans la table dashboard.t_suivi.
Vous renvoyez la valeur NEW, donc c'est normal. Voir https://www.postgresql.org/docs/10/stat … ML-TRIGGER pour les détails.
et si je rajoute les conditions DELETE et INSERT je reçois cette erreur:
ERROR: ERREUR: la condition WHEN du trigger INSERT ne peut pas référencer les valeurs OLD
Oui, OLD n'est pas référençable pour un INSERT, vu qu'il n'y a pas d'ancienne version de la ligne. Tout comme NEW n'est pas référençable pour un DELETE.
Guillaume.
Hors ligne
#5 29/03/2018 16:00:21
- bruhnil
- Membre
Re : Impossible de supprimer une entité avec un trigger
Merci pour ce retour.
J'ai trouvé une astuce permettant de faire ce que je voulais.
Je passe par deux triggers:
Le premier permet de rajouter ou mettre à jour les lignes de coordination.numerisation dans dashboard.t_suivi.
CREATE OR REPLACE FUNCTION update_t_suivi() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO dashboard.t_suivi (
id_coord,
lot,
cdd,
mission_moe,
id_prog,
id_nro,
numero,
insee,
com_dep,
statut,
emprise,
nom,
travaux,
longueur,
debut_trvx,
prog_dsp,
moa,
commentair,
envoi_moe
)
VALUES(
new.id_opp,
new.lot,
new.cdd,
new.phase,
new.id_prog,
new.id_nro,
new.numero,
new.insee,
new.com_dep,
new.statut,
new.emprise,
new.nom,
new.travaux,
new.longueur,
new.debut_trvx,
new.prog_dsp,
new.moa,
new.commentair,
new.envoi_moe)
;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
DROP TRIGGER IF EXISTS trg_update_t_suivi_num ON dashboard.t_suivi;
DROP TRIGGER IF EXISTS trg_update_t_suivi_num ON coordination.numerisation;
CREATE TRIGGER trg_update_t_suivi_num
AFTER UPDATE OR INSERT ON coordination.numerisation
FOR EACH ROW
EXECUTE PROCEDURE update_t_suivi();
Le deuxième trigger permet de supprimer les lignes de dashboard.t_suivi ne figurant pas ou plus dans coordination.numerisation.
CREATE OR REPLACE FUNCTION delete_t_suivi() RETURNS TRIGGER AS $$
BEGIN
WITH a_supprimer AS
(
SELECT *
FROM dashboard.t_suivi AS num
WHERE num.id_coord NOT IN
(SELECT DISTINCT id_opp
FROM coordination.numerisation opp
WHERE id_coord=id_opp
GROUP BY id_coord, id_opp
))
DELETE FROM dashboard.t_suivi a
USING a_supprimer b
WHERE a.id = b.id;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
DROP TRIGGER IF EXISTS trg_delete_t_suivi_num ON dashboard.t_suivi;
DROP TRIGGER IF EXISTS trg_delete_t_suivi_num ON coordination.numerisation;
CREATE TRIGGER trg_delete_t_suivi_num
AFTER UPDATE OR DELETE ON coordination.numerisation
FOR EACH ROW
EXECUTE PROCEDURE delete_t_suivi();
Hors ligne