【发布时间】:2014-08-03 07:40:00
【问题描述】:
我一直在查看documentation of postgresql triggers,但它似乎只显示了行级触发器的示例,但我找不到语句级触发器的示例。
特别是,不清楚如何在单个语句中迭代更新/插入的行,因为NEW 是针对单个记录的。
【问题讨论】:
标签: postgresql plpgsql triggers
我一直在查看documentation of postgresql triggers,但它似乎只显示了行级触发器的示例,但我找不到语句级触发器的示例。
特别是,不清楚如何在单个语句中迭代更新/插入的行,因为NEW 是针对单个记录的。
【问题讨论】:
标签: postgresql plpgsql triggers
OLD 和 NEW 为 null 或未在语句级触发器中定义。 Per documentation:
NEW数据类型
RECORD;为行级触发器中的INSERT/UPDATE操作保存新数据库行的变量。 这个变量是 null 在语句级触发器和DELETE操作中。
OLD数据类型记录;为行级触发器中的
UPDATE/DELETE操作保存旧数据库行的变量。 此变量在语句级触发器中为空,对于INSERT操作。
我的大胆强调。
在 Postgres 10 之前,这读起来略有不同,但效果大致相同:
...此变量在语句级触发器中未分配。 ...
虽然这些记录变量对于语句级触发器仍然没有用处,但一个非常新的功能是:
Postgres 10 引入了转换表。这些允许访问整个受影响的行集。 The manual:
AFTER触发器还可以利用转换表 来检查由触发语句更改的整个行集。CREATE TRIGGER命令将名称分配给一个或两个转换 表,然后函数可以引用这些名称,就好像它们 是只读的临时表。 Example 43.7 显示了一个示例。
点击手册链接获取代码示例。
在转换表出现之前,这种情况就更少见了。一个有用的例子是在某些 DML 命令之后发送notifications。
这是我使用的基本版本:
-- Generic trigger function, can be used for multiple triggers:
CREATE OR REPLACE FUNCTION trg_notify_after()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
PERFORM pg_notify(TG_TABLE_NAME, TG_OP);
RETURN NULL;
END
$func$;
-- Trigger
CREATE TRIGGER notify_after
AFTER INSERT OR UPDATE OR DELETE ON my_tbl
FOR EACH STATEMENT
EXECUTE PROCEDURE trg_notify_after();
对于 Postgres 11 或更高版本,请使用等效且不易混淆的语法:
...
EXECUTE FUNCTION trg_notify_after();
见:
【讨论】:
NEW 和 OLD 用于多记录情况,以及一些迭代这些情况的方法..