mysql的now()是语句级快照时间,sql server的getdate()是调用级实时采样;跨库迁移时直接替换会导致时间逻辑错误,需按语义差异选用变量缓存或sysdate()等对应函数。

别直接用 NOW() 去替换 GETDATE(),它们根本不是同一套语义体系下的函数——跨数据库写法照搬,时间逻辑大概率出错。
MySQL 里 NOW() 是语句快照,不是实时钟
你在一条 INSERT ... SELECT 或含子查询的 UPDATE 中反复调用 NOW(),得到的全是同一个时间戳。它锁定在语句开始执行那一刻,哪怕中间有 SLEEP(2) 也不变。
- 适合场景:给整批插入记录打统一“操作时间戳”,比如日志表批量写入
- 不适合场景:想为每一行计算“执行到这一行时的真实毫秒时间”
- 若真要实时,改用
SYSDATE();但注意它绕过查询缓存,且高并发下多次调用可能返回微秒级差异 - ORM(如 Django、SQLAlchemy)默认可能把
func.now()映射成NOW(),但若你手动拼 SQL 并期望行为像 SQL Server,就得主动换掉
SQL Server 里没有 NOW(),GETDATE() 行为更接近 MySQL 的 SYSDATE()
在 SQL Server 视图或查询中写 NOW(),会直接报错:Invalid column name 'NOW'。它的原生函数是 GETDATE(),每次调用都重新读系统时钟——哪怕在同一语句中出现两次,理论上也可能因执行间隔产生差异(尽管极小)。
- 视图定义中必须用
AS显式命名列,否则SELECT * FROM v_xxx会看到(No column name) -
GETDATE()返回datetime类型(精度 ~3.33ms),而SYSDATETIME()返回datetime2(7)(精度 100ns),后者更适合做毫秒级差值计算 - 索引视图禁止使用
GETDATE(),因为它是非确定性函数;试图创建会收到错误:Cannot create index on view ... because it contains the nondeterministic function 'GETDATE'
跨库迁移时最常踩的坑:把 NOW() 当成通用函数硬替换成 GETDATE()
MySQL 的 NOW() 是语句级冻结时间,SQL Server 的 GETDATE() 是调用级采样时间。如果你原来依赖 NOW() 在事务中保持一致(比如多表 INSERT 共享同一时间戳),直接换 GETDATE() 就会导致各表时间不一致。
- 正确做法:先确认业务是否真需要“语句内一致性”。需要的话,SQL Server 应改用变量缓存:
DECLARE @t DATETIME = GETDATE(); INSERT ... @t - PostgreSQL 用户注意:
NOW()行为同 MySQL 的NOW(),要实时得用clock_timestamp() - Oracle 用户注意:对应的是
SYSDATE(类似 MySQLSYSDATE()),不是NOW() - 别只看函数名,先查
@@version或文档确认数据库类型和版本,再选函数
真正难处理的不是语法,而是时间语义的隐含假设——你写的那行 GETDATE(),到底是想表达“此刻”还是“这句 SQL 开始时的此刻”,这个判断一旦错,下游所有时间比对、延迟统计、幂等控制都会偏移。










