在 Postgres 9.0 或更高版本中,在触发器定义(语句)中添加一个WHEN子句:CREATE TRIGGER
CREATE TRIGGER foo
BEFORE UPDATE
FOR EACH ROW
WHEN (OLD IS DISTINCT FROM NEW) -- parentheses required!
EXECUTE PROCEDURE ...;
仅适用于触发器BEFORE/ AFTER UPDATE,其中定义了OLD和。NEW尝试将此WHEN子句与INSERTorDELETE触发器一起使用时,您会遇到异常。
并相应地从根本上简化触发功能:
...
IF OLD.locked > 0 THEN
RAISE EXCEPTION 'Message';
END IF;
...
无需测试IF TG_OP='UPDATE' ...,因为此触发器仅适用于任何情况UPDATE。
或者将该条件也移到 WHEN 子句中:
CREATE TRIGGER foo
BEFORE UPDATE
FOR EACH ROW
WHEN (OLD.locked > 0
AND OLD IS DISTINCT FROM NEW)
EXECUTE PROCEDURE ...;
在您的触发函数中只保留一个无条件RAISE EXCEPTION,仅在需要开始时调用。
阅读细则:
在BEFORE触发器中,WHEN条件在函数正在执行或将要执行之前被评估,因此使用WHEN与在触发器函数开始时测试相同条件没有本质区别。请特别注意,NEW条件看到的行是当前值,可能已被早期触发器修改。此外,BEFORE触发器的WHEN条件不允许检查行的系统列NEW(例如oid),因为尚未设置这些列。
在AFTER触发器中,WHEN在行更新发生后立即评估条件,并确定事件是否排队以在语句结束时触发触发器。因此,当AFTER触发器的
WHEN条件未返回 true 时,无需将事件排队,也无需在语句末尾重新获取行。如果只需要为少数几行触发触发器,这可能会导致修改多行的语句显着加速。
有关的:
还要解决问题标题
是否可以动态循环遍历表的列?
是的。例子: