微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 datetimeoffset 时 SQL Server 行为发生变化

如何解决使用 datetimeoffset 时 SQL Server 行为发生变化

我使用 sql Server 已经有一段时间了,并注意到在使用 datetimeoffset 时行为发生了变化。

让我们举两个查询的例子,一个是在日期时间值中使用普通字符串比较,另一个是使用 datetimeoffset 类型 viz

$list = ActMaster::where('status',1)->whereHas('reviews',function($query){
    $query->select(\DB::raw('count(*) as row_count'))
          ->where('published','1')
          ->groupBy('act_id')
          ->orderBy('row_count','desc');
})->paginate(10);

我在 sql Server 2014 和 sql Server 2019 中执行了上述查询,不同之处在于第二个查询的执行,其中 sql Server 2019 将结果作为相应的日期

enter image description here

我想检查最新版本的 sql Server 中的 datetimeoffset 参数类型是否有一些行为变化。

解决方法

您在 SQL Server 2016's breaking changes 中预期并记录的行为。

在数据库兼容级别 130 下,从 datetimedatetime2 数据类型的隐式转换通过考虑小数毫秒来提高准确性,从而导致不同的转换值。只要 datetime 和 datetime2 数据类型之间存在混合比较方案,就使用显式转换为 datetime2 数据类型。有关详细信息,请参阅此 Microsoft Support Article

在 2016 年,Microsoft 更新了从旧的 datetime 数据类型转换为新数据类型的行为,以更加准确。以前像 datetime 这样的 2019-09-06 11:28:05.757 值转换为 datetime2(7)2019-09-06 11:28:05.7570000,但是,在 2016+ 中,它现在准确地转换为 2019-09-06 11:28:05.7566667。这是因为 datetime 精确到 1/300 秒,不是 1/1000,所以之前的转换实际上是在给值增加时间。

对于您的查询,您首先拥有 datetimeoffset(7)2019-09-06 11:28:05.7570000。然后将该值与 datetime2019-09-06 11:28:05.757 进行比较。由于这两种数据类型不同,一种被隐式转换为另一种。 datetimeoffset 具有更高的优先级,因此 datetime 值 (2019-09-06 11:28:05.757) 被转换为 datetimeoffset2019-09-06 11:28:05.7566667 小于您的其他 datetimeoffset2019-09-06 11:28:05.7570000

如前所述,在 2014 年(及之前),SQL Server 错误地将 datetime 值转换为 2019-09-06 11:28:05.7570000,该值小于自身。这就是行为不同的原因。

如果您想要相同的行为,我建议(正如重大更改所做的那样),使用显式转换,然后转换为 datetimeoffset(3)。例如,下面的代码不会在任一实例中返回结果集:

DECLARE @P1 datetimeoffset;
SET @P1 = '2019-09-06 11:28:05.757';

SELECT *
FROM (SELECT cast('2019-09-06 11:28:05.757' as datetime) as test_date) data
WHERE CONVERT(datetimeoffset(3),test_date) < @P1;

20142019 (Linux)

,

测试用例

select cast(test_date as datetimeoffset) d2ofs,@@version
from (
    select cast('2019-09-06 11:28:05.757' as datetime) as test_date
) data 

结果:

d2ofs   (No column name)
2019-09-06 11:28:05.7566667 +00:00  Microsoft SQL Server 2016 (SP2-CU12) (KB4536648) - 13.0.5698.0 (X64) 
    Feb 15 2020 01:47:30 
    Copyright (c) Microsoft Corporation
    Express Edition (64-bit) on Windows Server 2019 Standard 10.0 <X64> (Build 17763: ) (Hypervisor)

对比

d2ofs   (No column name)
2019-09-06 11:28:05.7570000 +00:00  Microsoft SQL Server 2014 (SP3-CU-GDR) (KB4535288) - 12.0.6372.1 (X64) 
    Dec 12 2019 15:14:11 
    Copyright (c) Microsoft Corporation
    Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 17763: ) (Hypervisor)

db<>fiddle

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。