我有一个列为 id 的表 my_table(整数),* 值 *(瓦尔查尔),和 * 修改 *(时间戳)。我希望在每次设置新值时通过触发器更新时间戳。我在一个查询中更改数千行,因此不希望使用行级触发器(aka FOR EACH ROW),并在一次调用中修改整个更新集,而不是每一行的数千个。
CREATE TRIGGER my_trigger
AFTER UPDATE OF value
ON my_schema.my_table
REFERENCING NEW TABLE AS updated OLD TABLE AS prev
FOR EACH STATEMENT
EXECUTE PROCEDURE my_schema.my_trigger_function()
我在创建过程中遇到错误:
[0A000]错误:不能为具有列列表的触发器指定转换表
如果我删除了“REFERENCING NEW TABLE AS updated OLD TABLE AS prev”,那么我如何访问更新的数据集?如果我删除了“OF value”部分,那么我将获得递归触发器调用,因为触发器会通过更改同一个表但不同的列来再次激发自己。因此,我想到的最佳解决方案是's来消除IF条件的第二次递归调用:
CREATE TRIGGER my_trigger
AFTER UPDATE
ON my_schema.my_table
REFERENCING NEW TABLE AS updated OLD TABLE AS prev
FOR EACH STATEMENT
EXECUTE PROCEDURE my_schema.my_trigger_function()
CREATE OR REPLACE FUNCTION my_schema.my_trigger_function()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF EXISTS(SELECT 1
FROM updated
INNER JOIN prev ON updated.modified = prev.modified) THEN
UPDATE my_schema.my_table
SET modified = NOW()
WHERE id IN (SELECT id FROM updated);
END IF;
RETURN NULL;
END;
$$;
如果我知道如何使用“AFTER UPDATE OF value”访问所有更新的行,而不使用 updated 和 prev,我会做得更好,这就是我在这里的原因。
1条答案
按热度按时间vwkv1x7d1#
您可以通过在声明中添加
WHEN (PG_TRIGGER_DEPTH() = 0)
来避免触发器的递归调用: