now()和current_timestamp在功能上无区别,但语法、使用场景及跨库兼容性差异显著:mysql建表仅认current_timestamp(无括号)作默认值,now()在此报错;postgresql中now()是函数、current_timestamp是伪常量,参数支持不同;sqlite和sql server根本不支持now()。

在绝大多数实际场景里,NOW() 和 CURRENT_TIMESTAMP 没有功能区别——它们返回相同时间、相同类型、相同精度、相同事务行为。但“没区别”不等于“能随便混用”,具体怎么写、在哪写、带不带括号,直接决定语句是否报错、是否跨库兼容、是否被 ORM 正确解析。
MySQL 建表时只能用 CURRENT_TIMESTAMP(不带括号)作默认值
这是最常踩的坑:在 CREATE TABLE 里写 DEFAULT NOW() 会报错 Invalid default value for 'xxx',哪怕你确认 NOW() 查询时完全可用。
-
CURRENT_TIMESTAMP(无括号)是合法的列默认值,支持ON UPDATE CURRENT_TIMESTAMP -
CURRENT_TIMESTAMP()(带空括号)虽语法通过,但易被误读为可传参,不推荐 -
NOW()或NOW(漏括号)在 DDL 中一律非法,会被当成列名或标识符解析 - 想带毫秒?必须显式写
CURRENT_TIMESTAMP(3)或NOW(3),但后者只允许出现在 DML/SELECT 中
PostgreSQL 中 NOW() 是函数,CURRENT_TIMESTAMP 是常量
二者返回值和事务冻结行为一致,但语法约束完全不同:一个要括号,一个不能加括号。
-
NOW()合法,NOW(3)也合法(返回带毫秒的timestamptz) -
CURRENT_TIMESTAMP合法(无括号),但CURRENT_TIMESTAMP()或CURRENT_TIMESTAMP(3)直接报错:function current_timestamp() does not exist - Django ORM 等工具可能只识别
CURRENT_TIMESTAMP(无括号)作为迁移默认值,NOW()可能解析失败
SQLite 和 SQL Server 根本不认 NOW()
这不是“风格差异”,而是语法错误。写错就执行失败,没有商量余地。
- SQLite:只有
datetime('now')或strftime('%Y-%m-%d %H:%M:%f', 'now');CURRENT_TIMESTAMP仅限建表默认值,不能用于SELECT - SQL Server:没有
NOW(),也没有CURRENT_TIMESTAMP();CURRENT_TIMESTAMP是GETDATE()别名,但不支持精度参数;需要毫秒用SYSDATETIME() - 跨数据库项目若硬写
NOW(),在 SQLite 或 SQL Server 上连第一条SELECT都跑不通
事务内时间冻结 vs 实时时间:别和 SYSDATE() 搞混
NOW() 和 CURRENT_TIMESTAMP 都返回事务启动时刻的时间戳,不是语句执行到那一行的“实时时间”。这点常被忽略,尤其在含 SLEEP() 或长耗时操作的调试中。
- 同一事务里多次调用
NOW(),结果完全相同 - 想获取真正“此刻”的时间?MySQL 用
SYSDATE(),PostgreSQL 用CLOCK_TIMESTAMP() - 别在触发器或存储过程里依赖
NOW()做秒级调度逻辑——它不会随语句推进而更新
真正麻烦的从来不是“选哪个函数”,而是同一个 SQL 文件要在 MySQL、PostgreSQL、SQLite 上跑通。CURRENT_TIMESTAMP(无括号)在前三者中都可用(SQLite 仅限 DDL),而 NOW() 在 PostgreSQL 和 SQLite 里直接非法。精度控制、括号规则、ORM 解析偏好——这些细节比函数名本身更决定成败。











