为什么从DATETIME到DATETIME2的转换似乎会改变值?

kam*_*ilk 13 sql t-sql sql-server datetime

我有一个比较两个日期的存储过程.从我的应用程序的逻辑,我期望它们是平等的.但是,比较失败了.这样做的原因是,一个值被存储为一个事实DATETIME,不得不CONVERT-ed到DATETIME2正在相比其他前DATETIME2.显然,这改变了它的价值.我做了这个小测试:

DECLARE @DateTime DATETIME='2018-01-18 16:12:25.113'
DECLARE @DateTime2 DATETIME2='2018-01-18 16:12:25.1130000'
SELECT @DateTime, @DateTime2, DATEDIFF(NANOSECOND, @DateTime, @DateTime2)
Run Code Online (Sandbox Code Playgroud)

这给了我以下结果: -333333ns的区别

为什么这些值之间存在333333ns的差异?我认为a DATETIME2,作为一种更精确的类型,应该能够准确地表示可以存储在一个中的所有值DATETIMEDATETIME2的文档只说:

转换来自datetime时,将复制日期和时间.分数精度扩展到7位数.

没有关于转换在值中添加或减去333333ns的警告!那么为什么会这样呢?

我正在使用SQL Server 2016.

编辑:奇怪的是,在不同的服务器上,我得到零差异.两者都是SQL Server 2016,但我遇到问题的那个兼容级别设置为130,我没有将它设置为120.在它们之间切换会改变这种行为.

edit2: DavidG在评论中建议我使用的值可以表示为DATETIME2但不是a DATETIME.所以我修改了我的测试以确保我分配的值@DateTime2是一个有效值DATETIME:

DECLARE @DateTime DATETIME='2018-01-18 16:12:25.113'
DECLARE @DateTime2 DATETIME2=CONVERT(DATETIME2, @DateTime)
SELECT @DateTime, @DateTime2, DATEDIFF(NANOSECOND, @DateTime, @DateTime2)
Run Code Online (Sandbox Code Playgroud)

这有点帮助,因为差异较小但仍不为零: -33ns的区别

Dan*_*man 12

SQL Server 2016中引入了一个重大变化,涉及datetime和datetime2的转换和比较.此知识库文章中详细介绍了这些更改.

总之,在SQL 2014和早期版本的转换过程中舍入了值,而现在考虑了全精度.这可以提高性能,但在转换和比较这些不同类型时会引入问题.