当表中的任何值被更新时触发函数更新时间戳属性

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

【讨论】:

以上是关于当表中的任何值被更新时触发函数更新时间戳属性的主要内容,如果未能解决你的问题,请参考以下文章

在数据透视表中附加数据时时间戳不更新

使用 REPLACE INTO 更新表中的时间戳

时间戳(自动)何时更新?

将数据插入另一个表时触发以更新带有时间戳的表

java 如何通过接口把远程Oracle表中的数据同步到Mysql

更新条目而不更新时间戳