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

问题描述 投票:0回答:2

使用 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();

有什么想法吗?

postgresql triggers ddl
2个回答
3
投票

似乎是一个疏忽:

FOR EACH ROW
丢失了:

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

说明书:

如果两者均未指定,则

FOR EACH STATEMENT
为默认

我的粗体强调。您不能在语句级触发器中引用

NEW
OLD
,这使得
WHEN
子句(引用
NEW
)成为语法错误 - 在任何版本的 Postgres 中:

语句级触发器也可以有

WHEN
条件,尽管 功能对他们来说不太有用,因为条件无法引用 表中的任何值。

Postgres 9.0 中的

WHEN
添加了
CREATE TRIGGER
子句。

不幸的是,罕见的情况

FOR EACH STATEMENT
是默认的。一定是有历史原因。

旁白:表达方式

NEW.is_default = true
只是
NEW.is_default
的一种吵闹方式。
boolean
值可以直接用作表达式。


0
投票

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

例如,条件触发器在 PostgreSQL 9.0 中引入,并且在 8.4 或更早版本中不存在,因此 8.4 或更早版本的服务器将不知道

WHEN ...
在那里意味着什么。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.