我的表中有很多触发器,但其中一个触发器的行为并不完全像我想要的那样。
这个计算产品和价格并返回订单的总价格 - 工作正常:
CREATE OR REPLACE FUNCTION ustawwartosczamowienia() RETURNS TRIGGER AS $$
DECLARE
przed NUMERIC;
po NUMERIC;
ile NUMERIC;
BEGIN
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
SELECT cena*zamowienieilosc INTO ile FROM zamowienie_zawiera INNER JOIN zamowienie on zamowienie.id=zamowienie_idzamowienie inner join egzemplarz on zamowienie_zawiera.egzemplarz_idegzemplarz=egzemplarz.id inner join produkt on egzemplarz.produkt_idprodukt = produkt.id WHERE zamowienieilosc = new.zamowienieilosc;
SELECT wartosczamowienia INTO przed FROM zamowienie WHERE zamowienie.id = new.zamowienie_idzamowienie;
po := przed+ile;
UPDATE zamowienie SET wartosczamowienia=po WHERE zamowienie.id = new.zamowienie_idzamowienie;
ELSE
RAISE NOTICE 'Nie ma czegoś takiego';
END IF;
RETURN NEW;
END
$$
LANGUAGE 'plpgsql';
CREATE TRIGGER zamowieniewartosc
AFTER INSERT OR UPDATE
ON zamowienie_zawiera
FOR EACH ROW
EXECUTE PROCEDURE ustawwartosczamowienia();
然后我看到有人为f.e.购买了商品。总共1024。所以我想把这笔钱存入这个人的个人账户,以便以后为忠诚的客户提供特别优惠。我写了类似的触发器:
CREATE OR REPLACE FUNCTION kontododaj() RETURNS TRIGGER AS $$
DECLARE
przed NUMERIC;
po NUMERIC;
ile NUMERIC;
klient_idklient RECORD;
BEGIN
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
SELECT sumazamowien INTO przed FROM klient WHERE klient.id = new.klient_idklient;
SELECT wartosczamowienia INTO ile FROM zamowienie WHERE wartosczamowienia = new.wartosczamowienia;
po := przed + ile;
UPDATE klient SET sumazamowien=po WHERE klient.id = new.klient_idklient;
ELSE
RAISE NOTICE 'Nie ma czegoś takiego';
END IF;
RETURN NEW;
END
$$
LANGUAGE 'plpgsql';
CREATE TRIGGER kontoplus
AFTER INSERT OR UPDATE
ON zamowienie
FOR EACH ROW
EXECUTE PROCEDURE kontododaj();
然后我查看某人的帐户,他们有2048而不是1024.我的触发器增加了两倍钱。我应该改变什么?
答案 0 :(得分:1)
在不了解数据库结构的情况下找到原因是不安的,即。表格的DDL和可能发挥作用的其他触发器的代码。
你写道“我的桌子上有很多触发器”,我怀疑它们之间存在一些链接反应。如果是这种情况,我建议使用非触发程序来实现类似的逻辑。
顺便说一下,函数kontododaj()中可能存在逻辑错误。但在指出特定的地方之前,让我简化代码。来自kontododaj()身体:
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
SELECT sumazamowien
INTO przed
FROM klient
WHERE klient.id = new.klient_idklient;
SELECT wartosczamowienia
INTO ile
FROM zamowienie
WHERE wartosczamowienia = new.wartosczamowienia;
po := przed + ile;
UPDATE klient
SET sumazamowien = po
WHERE klient.id = new.klient_idklient;
ELSE
...
以上代码段(以逻辑方式)等同于:
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
UPDATE klient
SET sumazamowien = sumazamowien + new.wartosczamowienia
WHERE klient.id = new.klient_idklient;
ELSE
...
现在,我怀疑这段代码应该在更新后执行。考虑当具有值1024的字段“wartosczamowienia”(订单的值)被设置为相同值1024时的情况。这将导致将1024添加到“sumazamowien”(订单的总值),这是错误的。 也许你应该这样试试:
IF TG_OP = 'INSERT'
THEN
UPDATE klient
SET sumazamowien = sumazamowien + new.wartosczamowienia
WHERE klient.id = new.klient_idklient;
ELSIF TG_OP = 'UPDATE'
AND new.wartosczamowienia <> old.wartosczamowienia
THEN
UPDATE klient
SET sumazamowien = sumazamowien + ( new.wartosczamowienia - old.wartosczamowienia )
WHERE klient.id = new.klient_idklient;
ELSE
...
答案 1 :(得分:0)
一个很可能的原因是你在一个表zamowienie上创建了两个触发器。 可以将多个触发器分配给PostgresSQL中的一个表。这与我之前使用的其他数据库不同。我刚刚遇到这个问题并解决了。
通过:
SELECT * FROM pg_trigger;
您可以看到分配给表的触发器。删除不必要的触发器,就可以了。