sysdatetime() 返回 datetime2(7),精度达100纳秒,但若存入datetime字段或转为字符串时未指定格式,会无声截断至毫秒;需全程使用datetime2(7)并避免隐式转换。

SYSDATETIME() 返回的是 datetime2(7),不是 datetime,直接用它就能拿到纳秒级精度——但前提是字段类型和上下文匹配,否则精度会无声丢失。
SYSDATETIME() 的返回类型和精度陷阱
它返回 datetime2(7),意味着最多保留 7 位小数(100 纳秒级),比如 2026-06-12 21:27:35.1234567。但如果你把结果插入或赋值给 DATETIME 类型字段,SQL Server 会自动截断到毫秒(3 位小数),且不报错。
-
DATETIME最大精度是 3.33 毫秒(实际存储为 0、3、7),SYSDATETIME()的后 4 位小数直接丢弃 - 如果目标列是
DATETIME2,必须显式指定精度,例如DATETIME2(7);写成DATETIME2默认是DATETIME2(7),但旧版本(如 SQL Server 2005)不支持datetime2,需确认兼容性 - 在 SELECT 中直接用
SYSDATETIME()没问题,但做字符串拼接或导出时,CONVERT(VARCHAR, SYSDATETIME(), 121)会默认只输出到毫秒(2026-06-12 21:27:35.123),丢失微秒/纳秒
插入时如何真正保留 SYSDATETIME 的全部精度
建表时字段类型必须匹配,且避免隐式转换。常见错误是用 DATETIME 存,以为“时间就是时间”,结果精度全废。
- 建表用
DATETIME2(7):CREATETABLElog_table(idINT,tsDATETIME2(7));
- 插入时直接用函数,不 CAST:
INSERTINTOlog_tableVALUES(1,SYSDATETIME());
- 不要写成
CAST(SYSDATETIME() AS DATETIME)或CONVERT(DATETIME, SYSDATETIME()),这等于主动降级 - 如果已有
DATETIME字段,改类型需ALTERCOLUMN ... TYPE DATETIME2(7),注意该操作会锁表,生产环境慎用
WHERE 条件中用 SYSDATETIME() 做高精度过滤要注意什么
时间戳精度越高,相等判断越容易失败——尤其是跨服务器、跨事务时,哪怕差 100 纳秒也查不到。
- 避免用
= SYSDATETIME()做精确匹配,几乎总为空;改用范围查询,例如:WHERE ts >= DATEADD(nanosecond,-1000000,SYSDATETIME()) AND ts
- 如果只是想查“最近几秒”的记录,用
DATEADD(second,-5,SYSDATETIME())更安全 - 在 JOIN 或子查询中使用
SYSDATETIME(),每次调用都是独立快照,同一语句中多次出现的SYSDATETIME()值可能不同(尽管通常只差几十纳秒)
SYSDATETIME() 和 GETDATE() 在实际场景中的取舍
不是“越精确越好”,得看用途。很多业务逻辑根本不需要纳秒级区分。
- 审计日志、变更追踪、分布式事件排序 → 必须用
SYSDATETIME()+DATETIME2(7) - 仅用于显示“今天”“昨天”或按小时聚合 →
GETDATE()足够,且兼容老系统 - 与 .NET 的
DateTime交互时注意:.NETDateTime最高精度是 100 纳秒,但默认序列化只到毫秒;若需完整精度,要用DateTimeOffset或手动格式化 - 备份/恢复或 Always On 可用性组中,不同节点的系统时钟偏差可能大于 100 纳秒,此时靠
SYSDATETIME()排序可能反而出错
真正难的不是调用函数,而是让整个链路——从字段定义、参数传递、应用层反序列化到最终展示——都对齐精度需求。一个 DATETIME 字段,就足以让前面所有纳秒努力归零。











