CURRENT_TIMESTAMP是SQL标准函数,返回数据库服务器执行语句时的当前时间戳,类型为TIMESTAMP WITH TIME ZONE或TIMESTAMP(依数据库而定);它不是客户端时间,也不是语句开始前就固定的常量,单条语句内值一致,但事务中多次调用可能因执行时机不同而产生微秒级差异。

CURRENT_TIMESTAMP 是什么,不是什么
CURRENT_TIMESTAMP 是 SQL 标准函数,返回执行该语句时数据库服务器的当前时间戳(带时区或不带时区,取决于具体数据库实现)。它不是“客户端时间”,也不是“语句开始前就固定的时间”——每次在查询中被求值时,只要出现在不同行或不同子查询里,就可能产生微秒级差异。
常见误解是把它当常量用。比如 SELECT CURRENT_TIMESTAMP, CURRENT_TIMESTAMP 两列理论上可能不完全相等(尤其高并发或慢查询场景),虽然实践中极少察觉。
不同数据库对 CURRENT_TIMESTAMP 的行为差异
PostgreSQL 默认返回带时区的 timestamptz;MySQL 5.6+ 中 CURRENT_TIMESTAMP 等价于 NOW(),默认无时区;SQL Server 用 GETDATE() 或 SYSDATETIME(),CURRENT_TIMESTAMP 是其同义词但精度固定为毫秒。
- PostgreSQL:支持
CURRENT_TIMESTAMP(precision),例如CURRENT_TIMESTAMP(3)控制小数位数 - MySQL:不支持精度参数,写
CURRENT_TIMESTAMP(3)会报错ERROR 1064 - SQLite:只支持
datetime('now'),CURRENT_TIMESTAMP是其别名,固定为 'YYYY-MM-DD HH:MM:SS' 格式,无毫秒
在 INSERT/UPDATE 中使用 CURRENT_TIMESTAMP 的典型陷阱
直接写 INSERT INTO logs (msg, created_at) VALUES ('test', CURRENT_TIMESTAMP) 没问题,但若字段定义为 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,要注意:
- MySQL 中,只有第一个
TIMESTAMP字段能自动用CURRENT_TIMESTAMP做默认值,第二个会报错 - PostgreSQL 允许多个字段设默认值,但
CURRENT_TIMESTAMP每次插入都重新求值,不是“事务开始时间” - 如果想让整条 INSERT 的所有行共享同一时间戳,得显式赋值:
WITH now AS (SELECT CURRENT_TIMESTAMP AS ts) INSERT INTO t (...) SELECT ..., ts FROM now, ...
需要“事务内统一时间”时怎么办
CURRENT_TIMESTAMP 在单条语句内是稳定的,但在一个事务中多次调用仍可能变化(尤其跨语句、跨锁等待)。真要保证事务内时间一致,不能依赖它。
- PostgreSQL:用
CLOCK_TIMESTAMP()(每次调用都取实时系统时间) vsTRANSACTION_TIMESTAMP()(返回事务开始时刻,恒定) - MySQL:没有内置事务时间戳函数,常用做法是在事务开头
SET @tx_start = NOW(),后续用@tx_start - 应用层控制更可靠:在代码里生成一次时间,传入所有相关 SQL 参数
真正容易被忽略的是:你以为的“当前时间”可能被数据库时区设置悄悄改写——查 SHOW TIMEZONE(PostgreSQL)或 SELECT @@time_zone(MySQL),别只看自己本地时钟。

















