У меня проблема с триггером. Вот мой триггер:

CREATE TRIGGER calcul_auto_ht AFTER INSERT OR UPDATE OR DELETE ON ligne_commande
FOR EACH ROW EXECUTE PROCEDURE f_montantht();

А вот функция, упомянутая в триггере:

CREATE FUNCTION f_montantht() RETURNS TRIGGER AS $montantht$
declare
montant numeric(7,2) := 0; 
montant_par_ligne record; 
remise integer;

begin

for montant_par_ligne
in (select (quantite * prixpdt) as "montant_ligne" from commande c
left join ligne_commande lc
on lc.codecommande = c.codecommande
join produit pd
on pd.codepdt = lc.codepdt
where c.codecommande = NEW.codecommande)

loop
montant := montant + montant_par_ligne.montant_ligne;
end loop;

select into remise coderemise
from commande
where codecommande = NEW.codecommande;
if remise is not null then
montant := montant * (1-remise/100.);
end if;

UPDATE commande
SET montantht = montant
WHERE NEW.codecommande = codecommande;

return NULL;
END;
$montantht$ LANGUAGE 'plpgsql';

Триггер работает нормально, когда я обновляю или добавляю значения в ligne_commande , но он не работает, когда я хочу удалить строку в ligne_commande . На самом деле я не вижу никаких изменений, но если я сделаю вставку или обновление сразу после того, как я смогу увидеть результаты удаления (но я не хочу, чтобы это всегда нужно было делать ..)

Я действительно не знаю почему, ты хоть представляешь?

Спасибо :)

0
Jil0 2 Май 2021 в 22:29

1 ответ

Лучший ответ

Триггеры ON DELETE не имеют объекта NEW. В этом случае вы должны ссылаться на значения, используя OLD.codecommande. Дополнительная информация: https://www.postgresql.org/docs/current/plpgsql -trigger.html

Попробуйте заменить использование NEW.codecommande чем-то вроде этого:

CASE WHEN TG_OP = 'DELETE' THEN OLD.codecommande ELSE NEW.codecommande END

Если это сработает, вы можете улучшить функцию триггера, переместив эту логику в переменную, которую вы объявляете до BEGIN, например (хотя я не уверен в вашем типе данных):

DECLARE
    _codecommande text := CASE WHEN TG_OP = 'DELETE' THEN OLD.codecommande ELSE NEW.codecommande END;
BEGIN
...

Если вам также нужна поддержка TRUNCATE, вам необходимо соответствующим образом настроить логику.

0
mike.k 2 Май 2021 в 19:36