我有一个触发器,以确保所有投票的总数不超过100:
CREATE FUNCTION limit_votes() RETURNS TRIGGER AS $limit_votes$
DECLARE
votes_total int;
BEGIN
votes_total := NEW.vote + (SELECT SUM(vote) FROM cars WHERE portfolio_id = NEW.portfolio_id AND car != NEW.car);
IF votes_total > 100 THEN
RAISE EXCEPTION 'votes_limit_exceeded';
END IF;
RETURN NEW;
END;
$limit_votes$ LANGUAGE plpgsql;
CREATE TRIGGER limit_votes BEFORE INSERT OR UPDATE ON cars FOR EACH ROW EXECUTE PROCEDURE limit_votes();
需要提到的是,“投票”可以被更新,因此不仅仅是INSERT。
这就是我的问题所在,因为一个用户可能会在汽车之间更改票数,然后触发器将被作为更新发出,导致单行更新的限制超过100,在其他更新降低其他票数之前。
希望这有意义。
我希望触发器在BEGIN ... COMMIT之后被调用,这样我可以在检查所有内容是否正确之前更新多行 - 但如果用户尝试将投票数更新为超过100,则还需引发异常并不保存结果。
CREATE CONSTRAINT TRIGGER limit_votes AFTER INSERT OR UPDATE ON cars DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE limit_votes();
- bettwäshINITIALLY DEFERRED
。来自文档:INITIALLY IMMEDIATE INITIALLY DEFERRED 如果约束可延迟,则此子句指定检查约束的默认时间。如果约束为 INITIALLY IMMEDIATE,则在每个语句之后进行检查。这是默认设置。如果约束为 INITIALLY DEFERRED,则仅在事务结束时进行检查。可以使用 SET CONSTRAINTS 命令更改约束检查时间。
- Jordan Silva