【问题标题】:Milliseconds wrong when converting from XML to SQL Server datetime从 XML 转换为 SQL Server 日期时间时出现毫秒错误
【发布时间】:2009-03-11 11:20:11
【问题描述】:

我遇到了将日期时间从 XML (ISO8601: yyyy-mm-ddThh:mi:ss.mmm) 转换为 SQL Server 2005 日期时间的问题。问题是转换毫秒时是错误的。我已经使用 nvarchar 中的 convert(datetime, MyDate, 126) 测试了隐式和显式转换,结果是一样的:

Original                Result
2009-10-29T15:43:12.990 2009-10-29 15:43:12.990
2009-10-29T15:43:12.991 2009-10-29 15:43:12.990
2009-10-29T15:43:12.992 2009-10-29 15:43:12.993
2009-10-29T15:43:12.993 2009-10-29 15:43:12.993
2009-10-29T15:43:12.994 2009-10-29 15:43:12.993
2009-10-29T15:43:12.995 2009-10-29 15:43:12.997
2009-10-29T15:43:12.996 2009-10-29 15:43:12.997
2009-10-29T15:43:12.997 2009-10-29 15:43:12.997
2009-10-29T15:43:12.998 2009-10-29 15:43:12.997
2009-10-29T15:43:12.999 2009-10-29 15:43:13.000

我的非广泛测试显示最后一位数字是 0、3 或 7。这是一个简单的舍入问题吗?毫秒精度很重要,失去/获得一个或两个不是一种选择。

【问题讨论】:

    标签: sql-server xml sql-server-2005


    【解决方案1】:

    是的,SQL Server 将时间舍入到 3.(3) 毫秒:

    SELECT CAST(CAST('2009-01-01 00:00:00.000' AS DATETIME) AS BINARY(8))
    SELECT CAST(CAST('2009-01-01 00:00:01.000' AS DATETIME) AS BINARY(8))
    
    0x00009B8400000000
    0x00009B840000012C
    

    如您所见,这些DATETIME 相差1 秒,它们的二进制表示相差0x12C,即十进制的300

    这是因为SQL ServerDATETIMEtime 部分存储为从午夜开始的1/300 秒记号数。

    如果您想要更高的精度,您需要将TIME 部分存储为单独的值。例如,将四舍五入到一秒的时间存储为 DATETIME,并将毫秒或您需要的任何精度存储为另一列中的 INTEGER

    这将让您使用复杂的DATETIME 算术,例如在DATETIME 上添加月份或查找工作日,您只需添加或减去毫秒并将结果连接为.XXXXXX+HH:MM 以获得有效的@987654338 @ 表示。

    【讨论】:

    • 我想说,不要使用 SQL Server 的 DateTime 数据类型。将值存储在 VARCHAR 中。
    • 谢谢,这很有启发性,虽然有点令人沮丧。
    【解决方案2】:

    因为precision issues mentioned by Quassnoi,如果你可以选择使用SqlServer 2008,你可以考虑使用datetime2 datatype,或者如果你只关心时间部分你可以使用time datatype

    Date and Time Data Types - 列出所有类型及其准确性

    在 Sql Server 2005 中,如果我需要 1 毫秒的精度,我将添加一个额外的 int 类型的毫秒列来存储毫秒数并从 dateTime 列中删除毫秒部分(将其设置为 000)。假设您还需要日期信息。

    【讨论】:

    • 我们一直在使用 SQL Server 2008 进行测试,但客户端仍在 2005 上。已建议升级。
    猜你喜欢
    • 2013-10-31
    • 2014-11-26
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2021-06-14
    相关资源
    最近更新 更多