You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL存储过程日志时间戳异常:多次插入记录时间相同

问题原因及解决方案

问题根源

你遇到的问题是PostgreSQL中now()函数的特性导致的:now()(等价于transaction_timestamp())返回的是当前事务的启动时间,而非语句执行的实时时间。如果你的整个查询批次是在同一个事务内执行的,那么不管多少次调用存储过程,now()都会返回事务启动时的时间,所以所有记录的时间戳完全一致。

解决方案

有两种直接的修复方式:

1. 替换为clock_timestamp()

clock_timestamp()会返回语句执行的真实当前时间,每次调用都会获取最新的时间值。修改你的存储过程:

CREATE OR REPLACE PROCEDURE admin.log_event(
    IN log_message character varying,
    IN param1 character varying DEFAULT NULL::character varying,
    IN param2 character varying DEFAULT NULL::character varying)
LANGUAGE 'plpgsql'
AS $BODY$
  begin
    insert into admin.event_log (dt, msg, param_1, param_2) values (clock_timestamp(), log_message, param1, param2);
  end;
$BODY$;

不需要额外声明ts变量,直接在插入语句中使用clock_timestamp()即可。

2. 给表字段设置默认值(更推荐)

如果dt字段的唯一作用就是记录插入时间,可以直接给该字段设置默认值为clock_timestamp(),这样存储过程不用手动传递时间,避免人为失误:
首先修改表结构:

ALTER TABLE admin.event_log ALTER COLUMN dt SET DEFAULT clock_timestamp();

然后简化存储过程:

CREATE OR REPLACE PROCEDURE admin.log_event(
    IN log_message character varying,
    IN param1 character varying DEFAULT NULL::character varying,
    IN param2 character varying DEFAULT NULL::character varying)
LANGUAGE 'plpgsql'
AS $BODY$
  begin
    insert into admin.event_log (msg, param_1, param_2) values (log_message, param1, param2);
  end;
$BODY$;

这样每次插入记录时,PostgreSQL会自动用当前实时时间填充dt字段,无需在存储过程中处理时间逻辑。

内容的提问来源于stack exchange,提问作者WV_Mapper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 16:05:06