Postgres 触发器仅在 NEW.column = true 时执行过程

Postgres trigger to only execute procedure when NEW.column = true

使用 PostgreSQL - 我正在尝试触发仅当 NEW(插入或更新)行的 is_default 列值设置为 boolean true 时才运行触发器的过程.

这是我试过的方法,但我的 WHEN 行出现语法错误:

CREATE TRIGGER trigger_price_group_default_price_handler
    BEFORE UPDATE OR INSERT
    ON price_groups
    WHEN (NEW.is_default = true)
    EXECUTE PROCEDURE clear_default_price_group();

有什么想法吗?

在看似正确的代码中出现明显无法解释的语法错误的最可能原因是您使用的服务器版本不理解语法。

例如,条件触发器是 introduced in PostgreSQL 9.0, and are not present in 8.4 or older,因此 8.4 或更旧的服务器将不知道 WHEN ... 在那里意味着什么。

我试图在 pgsql-docs 邮件列表上提出我们应该在功能描述旁边包含 "Since [version]" 的论点,但每个人似乎都更喜欢指导人们阅读他们版本的文档。所以我还没有走远。至少 PostgreSQL 有快速链接到其他版本的文档,不像太多的项目 (cough Hibernate cough ).

(这也意味着您使用的是旧的且不受支持的 PostgreSQL 版本,应该升级)。

似乎是疏忽:FOR EACH ROW 缺失:

CREATE TRIGGER trigger_price_group_default_price_handler
 BEFORE UPDATE OR INSERT ON price_groups
 <b>FOR EACH ROW</b>
 WHEN (NEW.is_default)
 EXECUTE PROCEDURE clear_default_price_group();

如果不提供,per documentation:

If neither is specified, FOR EACH STATEMENT is the default.

大胆强调我的。并且您不能在语句级触发器中引用 NEWOLD,这使得 WHEN 子句(引用 NEW)成为语法错误 - 在任何Postgres 版本:

Statement-level triggers can also have WHEN conditions, although the feature is not so useful for them since the condition cannot refer to any values in the table.

除此之外,您至少需要 Postgres 9.0 才能在 CREATE TRIGGER

中使用 WHEN 子句

我认为罕见的情况 FOR EACH STATEMENT 是默认设置,这有点不幸。我想一定是出于历史原因。

旁白:表达式 NEW.is_default = true 只是 NEW.is_default 的一种嘈杂表达方式。 boolean 值可以直接用作表达式。