You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server:DATEPART提取datetime毫秒值出现舍入异常的原因及解决

问题原因与解决方法

核心原因:SQL Server datetime 类型的精度限制

SQL Server 的 datetime 类型并非精确到1毫秒,它的时间精度是 3.33毫秒(即1/300秒)。也就是说,datetime 只能存储以下固定间隔的时间值:0、3、7、10、13...以此类推(对应0.000s、0.003s、0.007s、0.010s等)。

当你用 GETDATE() 生成默认值时,系统会将实际当前时间舍入到最近的datetime可存储精度值。比如你看到表面上的.7毫秒,实际存储的是.66667秒(约666.67毫秒)——这是最接近实际时间的datetime允许值。

为什么DATEPART()和CONVERT()表现不同?

  • DATEPART(ms, 列名) 提取的是datetime列实际存储的近似值,所以会显示666、667这类符合3.33毫秒间隔的数值,看起来像"舍入",但其实是读取了真实存储的值。
  • CONVERT函数在格式化datetime时,会将存储的近似值四舍五入为更易读的显示值,比如把.66667秒格式化为700毫秒(即显示为.7),但这只是显示层面的优化,并非实际存储的精确值。

解决方法

如果你需要精确到1毫秒的时间存储和读取,建议:

  • 将列类型从datetime改为**datetime2(3)**:datetime2支持最高100纳秒的精度,datetime2(3)则精确到1毫秒,完全满足需求。
  • 若无法修改表结构,要读取和CONVERT显示一致的毫秒值,可以用以下方式:
    SELECT CAST(RIGHT(CONVERT(VARCHAR(23), 你的datetime列, 121), 3) AS INT) AS 显示一致的毫秒值
    
    注意:此方法获取的是格式化后的显示值,并非datetime实际存储的精确值,仅用于和CONVERT显示对齐。

测试验证(结合你的场景)

比如你的测试表脚本:

CREATE TABLE TestDateTime (
    ID INT IDENTITY(1,1),
    CreateTime DATETIME DEFAULT GETDATE(),
    CreateTime2 DATETIME2(3) DEFAULT SYSDATETIME()
)

插入数据后执行查询:

SELECT 
    CreateTime,
    DATEPART(ms, CreateTime) AS DATEPART提取的毫秒,
    CONVERT(VARCHAR(23), CreateTime, 121) AS CONVERT格式化结果,
    CreateTime2,
    DATEPART(ms, CreateTime2) AS DATETIME2提取的毫秒
FROM TestDateTime

会看到CreateTime的DATEPART结果是666或667,而CONVERT显示为.700,CreateTime2则能精确存储并提取实际的毫秒值。

内容的提问来源于stack exchange,提问作者Fevzi Kartal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:16:07