我有代码只在更新单个特定列时触发触发器。触发器用于触发一个函数,该函数将引发一个postgres“notify”事件,我正在监听它,并且需要测试并验证新输入的详细信息。 account_details表上有许多值可以更改,不需要帐户验证,因此仅在AFTER UPDATE(没有时间)的触发器是不好的。
CREATE TRIGGER trigger_update_account_details
AFTER UPDATE ON account_details
FOR EACH ROW
WHEN (OLD.email IS DISTINCT FROM NEW.email)
EXECUTE PROCEDURE notify_insert_account_details();
但是,如果许多列中的一个发生变化,我想触发触发器
WHEN (OLD.email IS DISTINCT FROM NEW.email OR
OLD.username IS DISTINCT FROM NEW.username OR
OLD.password IS DISTINCT FROM NEW.password)
但OR不是触发器的有效关键字。试图搜索要使用的关键字而不是OR似乎没有提出任何由于单词OR的性质:-(
这是一种误解。 WHEN
clause of the trigger definition expects a boolean
expression,你可以使用OR
运算符。这应该工作(假设所有列实际存在于表account_details
中)。我自己使用类似的触发器:
CREATE TRIGGER trigger_update_account_details
AFTER UPDATE ON account_details
FOR EACH ROW
WHEN (OLD.email IS DISTINCT FROM NEW.email
OR OLD.username IS DISTINCT FROM NEW.username
OR OLD.password IS DISTINCT FROM NEW.password)
EXECUTE PROCEDURE notify_insert_account_details();
评估表达式的成本很低,但这可能比替代方案更可靠:
CREATE TRIGGER ... AFTER UPDATE OF email, username, password ...
当列的任何列在
UPDATE OF
命令的column_name
列表中列为目标时,将触发特定于列的触发器(使用UPDATE
SET
语法定义的触发器)。即使未触发触发器,列的值也可能会更改,因为不考虑BEFORE UPDATE
触发器对行内容所做的更改。相反,像UPDATE ... SET x = x ...
这样的命令会在列x上触发一个触发器,即使该列的值没有改变。
ROW
类型语法更短,可以检查许多列(做同样的事情):
CREATE TRIGGER trigger_update_account_details
AFTER UPDATE ON account_details
FOR EACH ROW
WHEN ((OLD.email, OLD.username, OLD.password, ...)
IS DISTINCT FROM
(NEW.email, NEW.username, NEW.password, ...))
EXECUTE PROCEDURE notify_insert_account_details();
或者,检查行中的每个可见用户列:
...
WHEN (OLD IS DISTINCT FROM NEW)
...
我认为你不需要WHEN
条款。您可以在UPDATE子句中指定有问题的列:
CREATE TRIGGER trigger_update_account_details
AFTER UPDATE OF email, username, password ON account_details
FOR EACH ROW
EXECUTE PROCEDURE notify_insert_account_details();