now()用于mysql中更新datetime字段,如update orders set updated_at = now() where id = 123;它返回服务器当前时间(yyyy-mm-dd hh:mm:ss),受时区影响,不适用于sql server等其他数据库。

MySQL 里用 NOW() 更新日期字段
MySQL 中最常用的是 NOW(),它返回当前日期和时间(精确到秒),类型是 DATETIME。直接在 UPDATE 语句中调用即可,不需要额外转换:
UPDATE orders SET updated_at = NOW() WHERE id = 123;
注意:NOW() 是函数调用,括号不能省;如果字段是 DATE 类型(只存日期),NOW() 会自动截断时间为 YYYY-MM-DD,但建议显式用 CURDATE() 更清晰。
- 若字段定义为
TIMESTAMP,且设置了DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,则无需手动更新——数据库会自动触发 -
NOW()返回值受 MySQL 服务器时区影响,不是客户端本地时间;可通过SELECT @@time_zone;查看当前时区 - 避免在 WHERE 条件中依赖
NOW()做范围比较后立即更新,因为两次调用可能产生毫秒级偏差(虽极少影响业务,但高并发下需留意)
SQL Server 里必须用 GETDATE(),别写成 NOW()
SQL Server 没有 NOW() 函数,写错会报错:Invalid column name 'NOW' 或 Cannot find either column "dbo" or the user-defined function or aggregate "dbo.NOW"。正确写法是:
UPDATE users SET last_login = GETDATE() WHERE user_id = 456;
GETDATE() 返回 DATETIME 类型(精度约 3.33ms),SQL Server 2016+ 推荐改用 SYSDATETIME()(精度达 100ns)或 SYSDATETIMEOFFSET()(带时区)。
-
GETDATE()和SYSDATETIME()都基于服务器操作系统时间,不随客户端时区变化 - 如果字段是
DATETIME2,用SYSDATETIME()更匹配类型,避免隐式转换开销 - 千万别在视图或函数里误用
NOW()—— SQL Server 会直接拒绝创建
跨数据库写法?别硬凑,按目标库选函数
没有“一次编写、到处运行”的日期函数。PostgreSQL 用 NOW(),但返回的是 TIMESTAMPTZ;Oracle 用 SYSDATE;SQLite 用 datetime('now')。强行抽象成统一字符串容易出错。
- ORM 如 SQLAlchemy 或 MyBatis 可通过方言配置自动替换,但纯 SQL 脚本必须明确指定目标数据库函数
- 迁移脚本中混用
NOW()和GETDATE()是常见翻车点,上线前务必在目标环境验证 - 如果业务逻辑要求“更新为 UTC 时间”,MySQL 要用
UTC_TIMESTAMP(),SQL Server 得用GETUTCDATE(),二者不可互换
为什么更新后查不到刚设的时间?检查字段类型和默认值
执行了 UPDATE ... = NOW() 却发现字段仍是旧值或 NULL,大概率不是函数问题,而是字段本身限制:
- 字段定义为
DATE,而你传入了NOW()(含时分秒),部分旧版 MySQL 会静默转为'0000-00-00'(取决于 SQL mode) - 字段有
DEFAULT CURRENT_TIMESTAMP但没加ON UPDATE CURRENT_TIMESTAMP,导致 UPDATE 时不触发自动更新 - 字段允许 NULL 且未设默认值,而你的 UPDATE 语句漏写了该字段(即没在 SET 后列出),它就保持原值不变
- 事务未提交(尤其在命令行客户端或某些 ORM 的 auto-commit 关闭状态下)
最稳妥的做法:先 SELECT 确认字段类型和约束,再针对性选函数,最后用 SELECT 验证结果。时间类字段的隐式行为比想象中更难调试。










