SQL Server 2017问题与日期时间数据类型

Mit*_*ari 2 sql-server sql-server-2016 sql-server-2017

我有一个简单的表,该表由5条记录(以毫秒为单位)组成。我将数据库从2016升级到2017 SQL Server时遇到了问题 此处附有两个图像,用于比较2016和2017 SQL Server结果的结果。我不明白为什么会在2017年出现这种不良行为。

这是2017 SQL Server中的错误吗??

在这两种情况下,表列数据类型在这两个日期时间数据类型中都是相同的。

SQL Server 2016输出

SQL Server 2017输出

这是创建表查询。

    USE [Test]
    GO

    CREATE TABLE [dbo].[TestVisionBot3](
        [FileId] [varchar](50) NULL,
        [OrgId] [nchar](10) NOT NULL,
        [ProjectId] [varchar](50) NULL,
        [CreatedAt] [datetime] NULL,
        [LockedUserid] [nvarchar](50) NULL
    ) ON [PRIMARY]
    GO
Run Code Online (Sandbox Code Playgroud)

这也是示例数据。

    1a  1           2a  2018-04-29 10:30:30.010 test
    3a  1           2a  2018-04-29 10:30:30.553 test
    2a  1           2a  2018-04-29 10:30:30.557 test
    4a  1           2a  2018-04-29 10:30:30.560 test
    5a  1           2a  2018-04-29 10:30:30.563 test
Run Code Online (Sandbox Code Playgroud)

Dhr*_*shi 5

背景资料:

优先规则

当运算符组合两个不同数据类型的表达式时,数据类型优先级规则将指定优先级较低的数据类型转换为优先级较高的数据类型。

因此,在您的where子句中,当您将datetime与datetime2进行比较时,由于datetime2具有更高的优先级,因此datetime上升到了datetime2。

现在,SQL Server 2017会发生什么变化?在新版本的SQL Server中,隐式转换将遵循从datetime到datetime2的转换规则,如下所述

从datetime转换为datetime2规则:

从日期时间转换时,将复制日期和时间。小数精度扩展到7位数字。以下示例显示了将datetime值转换为datetime2值的结果。

DECLARE @datetime datetime = '2018-04-29 10:30:30.553';
DECLARE @datetime2 datetime2 = @datetime;

SELECT @datetime2 AS '@datetime2', @datetime AS '@datetime';

--Result  
--@datetime2                  @datetime
------------------------- ---------------------------
--22018-04-29 10:30:30.5533333 2018-04-29 10:30:30.553
Run Code Online (Sandbox Code Playgroud)

现在,您之前的转换实际上是字符串文字到datetime2的转换。因此,它遵循不同的规则。

字符串文字到datetime2的转换规则:

时间的字符串部分被分配给时间和日期,因为没有外推精度,而是用0进行右填充以提高精度。 顺便说一句,这也是在sql server 2017之前的版本中将datetime转换为datetime2的操作。

更多说明: 当您将'2018-04-29 10:30:30.553'转换为datetime2时,它将转换为'2018-04-29 10:30:30.5530000',因为它将字符串文字转换为datetime2

在where子句中比较存储的datetime值与datetime2值时,优先级规则适用,因此datetime碰到了datetime2。因此,当'2018-04-29 10:30:30.5530000'(日期时间值)更改为Datetime2值时,小数部分将增强并变得大于原始值。

因此,您的.553扩展为.553333,大于.533

DECLARE @datetime datetime = '2018-04-29 10:30:30.553';
DECLARE @strliteral varchar(max)='2018-04-29 10:30:30.553';
DECLARE @datetime2 datetime2 = @datetime;

SELECT 
@datetime2 AS '@datetime2', 
@datetime AS '@datetime', 
cast(@strliteral as datetime2) AS strtoDatetime2,
cast(@datetime as datetime2) AS datetimetoDatetime2;

-- @datetime2                   @datetime               strtoDatetime2 
datetimetoDatetime2
-- 2018-04-29 10:30:30.5533333  2018-04-29 10:30:30.553 2018-04-29 10:30:30.5530000 2018-04-29 10:30:30.5533333
Run Code Online (Sandbox Code Playgroud)

见下图 在此处输入图片说明