【发布时间】:2021-12-13 05:24:17
【问题描述】:
在 Azure SQL 数据库中,我们使用外部表从另一个 Azure SQL 数据库中查询数据。按 DATETIME 列过滤外部表时,如果毫秒的最后一位为 3 或 7,则不返回任何行。如果最后一位为 0,则查询按预期工作。
示例:
/* MILLISECONDS ENDS WITH 0 - WORKS AS EXPECTED*/
DECLARE @myDate DATETIME = '2021-10-27 12:00:00.000';
SELECT * from dbo.ext_datetimetest where myDate = @myDate;
GO
/* MILLISECONDS ENDS WITH 3 OR 7 - RETURNS NOTHING*/
DECLARE @myDate DATETIME = '2021-10-27 12:00:00.003';
SELECT * from dbo.ext_datetimetest where myDate = @myDate;
GO
注意事项:
- 只有参数化查询受到影响。在 where 子句中硬编码日期时间值的任何查询都可以按预期工作。
- 只有跨数据库查询受到影响。直接在源数据库上运行查询按预期工作。
- 我们的代码多年来一直按预期工作,上周才开始出现这种行为。
- 这只发生在我们的测试和生产环境中。我们的开发环境对所有日期时间值都按预期工作。
复制步骤:
/* EXECUTE IN DATABASE #1 */
CREATE TABLE dbo.datetimetest (myDate DATETIME NOT NULL);
GO
INSERT dbo.datetimetest (myDate)
VALUES
('2021-10-27 12:00:00.000')
,('2021-10-27 12:00:00.003')
,('2021-10-27 12:00:00.007')
,('2021-10-27 12:00:00.010')
;
GO
/* EXECUTE IN DATABASE #2 */
CREATE EXTERNAL TABLE dbo.ext_datetimetest ( myDate DATETIME NOT NULL)
WITH (DATA_SOURCE = [DATABASE #1], SCHEMA_NAME = N'dbo', OBJECT_NAME = N'datetimetest');
GO
/* SELECT ALL ROWS TO CONFIRM VALUES */
SELECT * FROM dbo.ext_datetimetest;
/* These all work because the filters are hardcoded */
SELECT * from dbo.ext_datetimetest where myDate = '2021-10-27 12:00:00.000';
SELECT * from dbo.ext_datetimetest where myDate = '2021-10-27 12:00:00.003';
SELECT * from dbo.ext_datetimetest where myDate = '2021-10-27 12:00:00.007';
SELECT * from dbo.ext_datetimetest where myDate = '2021-10-27 12:00:00.010';
GO
/* VARIABLES ONLY WORK IF LAST DIGIT IS 0 */
DECLARE @myDate DATETIME;
SET @myDate = '2021-10-27 12:00:00.000'; SELECT * from dbo.ext_datetimetest where myDate = @myDate; /* WORKS */
SET @myDate = '2021-10-27 12:00:00.003'; SELECT * from dbo.ext_datetimetest where myDate = @myDate; /* RETURNS NOTHING */
SET @myDate = '2021-10-27 12:00:00.007'; SELECT * from dbo.ext_datetimetest where myDate = @myDate; /* RETURNS NOTHING */
SET @myDate = '2021-10-27 12:00:00.010'; SELECT * from dbo.ext_datetimetest where myDate = @myDate; /* WORKS */
GO
【问题讨论】:
-
首先,用equals查询日期时间值是很不寻常的。我假设您知道
datetime日期类型仅存储有限的精度?来自文档“四舍五入到 .000、.003 或 .007 秒的增量”。 -
如果
@myDate在某处转换为datetime2,那么2021-10-27 12:00:00.003将变为2021-10-27 12:00:00.0033333- 数据类型是否已更改?或者数据库兼容级别从<130更改为>=130? -
我认为你在正确的轨道上。环境中一定发生了一些变化,但我不知道是什么。所有数据库都设置为兼容级别 130。sys.databases 中的所有设置在 Dev Test 和 Prod 之间都是相同的。
标签: sql-server datetime azure-sql-database cross-database