删除后 - 触发

时间:2021-05-02 19:29:23

标签: sql postgresql function triggers sql-function

我的触发器有问题。这是我的触发器:

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 中的一行时,它不起作用。事实上,我看不到任何更改,但如果我在之后立即执行插入或更新,我将能够看到删除的结果(但我不想总是需要这样做..)

我真的不知道为什么,你有什么想法吗?

谢谢:)

1 个答案:

答案 0 :(得分:0)

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,则需要适当调整逻辑。