当表中的任何值被更新时触发函数更新时间戳属性
Posted
技术标签:
【中文标题】当表中的任何值被更新时触发函数更新时间戳属性【英文标题】:Trigger function to update timestamp attribute when any value in the table is updated 【发布时间】:2021-12-07 23:38:27 【问题描述】:每当表中的任何值更新时,我都想将时间戳属性“register_updated”更新为 current_timestamp。
这是我的功能
CREATE OR REPLACE FUNCTION fn_register_updated()
RETURNS trigger language plpgsql AS $$
BEGIN
UPDATE tb_register
SET register_updated = CURRENT_TIMESTAMP
WHERE (OLD.* IS DISTINCT FROM NEW.*);
RETURN NEW;
END;
$$;
CREATE TRIGGER tg_register_updated
BEFORE UPDATE
ON tb_register
FOR EACH ROW
EXECUTE PROCEDURE fn_register_updated();
但是每当我对表运行更新时,我都会收到以下错误:
SQL statement "UPDATE tb_register
SET register_updated = CURRENT_TIMESTAMP"
PL/pgSQL function fn_register_updated() line 3 at SQL statement
SQL statement "UPDATE tb_register
SET register_updated = CURRENT_TIMESTAMP"
PL/pgSQL function fn_register_updated() line 3 at SQL statement
SQL statement "UPDATE tb_register
关于如何解决这个问题的任何想法?
我正在努力在函数体内使用 UPDATE。
谢谢,
【问题讨论】:
您不希望这样做,因为通过更新触发器进行更新将设置递归(您在错误消息中看到)并且不会成功。你想要的是NEW.register_updated = CURRENT_TIMESTAMP;
而不是UPDATE
。
@AdrianKlaver 谢谢!那么,表更新后使用函数内的 UPDATE 语句来更新列是不可能的?
我在这里读到:***.com/questions/14137932/…,可以通过添加 WHERE 语句来避免递归。我已经相应地更新了我的代码,但我不确定如何指示“更新任何值”
重点是 1) UPDATE
是不需要的句号。 2) 您在UPDATE
之前更新,尽管它是否是AFTER
触发器并不重要。 3)你仍然会得到递归。 NEW
记录具有 register_updated
字段,只需执行 NEW.register_updated = CURRENT_TIMESTAMP; RETURN NEW;
。这将更改触发器中该字段的值,并且不会导致再次触发 UPDATE
触发器。这真的很简单,不要打这个过程。阅读此plpgsql trigger。
【参考方案1】:
为您提供示例代码:
CREATE OR REPLACE FUNCTION fn_register_updated()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
begin
new.register_updated = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$function$;
create trigger tg_register_updated before
update
on
tb_register for each row execute function fn_register_updated();
【讨论】:
以上是关于当表中的任何值被更新时触发函数更新时间戳属性的主要内容,如果未能解决你的问题,请参考以下文章