2

有时,将 DateTimeOffset 转换为 Datetime 似乎会将 DateTimeOffset 字段带回 UTC

我想查找在特定日期之间发生的所有订单。OrderDateTime 存储为 DateTimeOffset。

DECLARE @StartDate DATETIME = '20130723'
       ,@EndDate   DATETIME = '20130724'

SELECT cn.orderdatetime,
       LocalTime = CAST(orderdatetime AS datetime),
       facilityid
FROM ConsignmentNote cn
WHERE CAST(OrderDateTime AS DATETIME) BETWEEN @StartDate AND @EndDate

此查询的结果是(如您所料)

OrderDateTime                         LocalTime                  Facilityid
2013-07-23 08:26:02.9120644 +10:00    2013-07-23 08:26:02.913    84
2013-07-23 08:27:43.9571506 +10:00    2013-07-23 08:27:43.957    84
2013-07-23 10:24:54.2930893 +10:00    2013-07-23 10:24:54.293    84

但我还需要在 facilityID 上过滤此结果集 - 但如果我将 facilityId 添加到查询中:

DECLARE @StartDate DATETIME = '20130723'
       ,@EndDate   DATETIME = '20130724'

SELECT cn.orderdatetime,
       LocalTime = CAST(orderdatetime AS datetime),
       facilityid
FROM ConsignmentNote cn
WHERE CAST(OrderDateTime AS DATETIME) BETWEEN @StartDate AND @EndDate
AND FacilityId = 84

我得到以下结果

orderdatetime                       LocalTime               facilityid
2013-07-23 10:24:54.2930893 +10:00  2013-07-23 10:24:54.293 84

是什么赋予了?为什么在查询中添加另一个参数与日期有关?(nb facilityID is int in consignmentNote Table)

只是为了证明这一点 - 如果我将 StartDate 移回一天到“20130722”,我会得到我正在寻找的 3 行结果,这似乎表明:

 CAST (OrderDateTime as DateTime) 

是否(有时?)根据其在 SELECT 或 WHERE 子句中是否有不同的处理方式,或者是否有其他参数?(好吧,这似乎不是一个统一的处理方式)

谁能指出我解决这个问题的任何方向?它可能是服务包或修补程序

Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) 2011 年 6 月 17 日 00:54:03 版权所有 (c) Microsoft Corporation Enterprise Edition (64-bit) o​​n Windows NT 6.1 (Build 7601: Service Pack 1)

顺便说一句 - 我知道如果我创建一个只包含这些值的表 - 这一切都可以按照您的预期(下面的代码)正常工作 - 所以它必须是环境的 - 是吗?

CREATE TABLE #temp (orderdatetime DATETIMEOFFSET,facilityid int)
INSERT INTO #temp VALUES ('2013-07-23 08:26:02.9120644 +10:00',84)
INSERT INTO #temp VALUES ('2013-07-23 08:27:43.9571506 +10:00',84)
INSERT INTO #temp VALUES ('2013-07-23 10:24:54.2930893 +10:00',84)

SELECT     orderdatetime,CAST(orderdatetime AS datetime),facilityid
FROM #temp 
WHERE    CAST(OrderDateTime AS DATETIME) BETWEEN @StartDate AND @EndDate
AND facilityid =84

DROP TABLE #temp
4

2 回答 2

1

这家伙试图做与你偶然发现的相反的事情。也就是说,他试图将他的 datetimeoffsets 转换为 UTC。但是有一些关于这种类型的铸造的讨论,我认为你会发现相关的。

在测试以下内容时:

DECLARE @Something datetimeoffset(7)

SET @Something = '2008-12-19 17:30:09.1234567 +11:00'

SELECT 1
WHERE DATEPART(hour, convert(datetime, @Something)) = 17

select cast(@Something as datetime)
select convert(datetime, @Something, 109)

看来 CONVERT 不会在 WHERE 子句中将时区更改为 UTC,也不会在 SELECT 子句中更改时区。但是,在转换中使用任何样式都会更改为 UTC。

希望这可以帮助。

于 2013-07-23T03:52:58.240 回答
1

您在该列上有索引吗?如果是这样,我认为您会看到KB2715289中描述的问题的另一种变体。

根据那篇文章,问题已解决:

我建议您手动或通过 Microsoft Update 应用最新更新,看看您是否仍有问题。

于 2013-08-11T20:24:43.127 回答