我正试图通过ETL作业将字符串转换为DateTimeOffset
(在SQL Server中)。基本上,我的字符串看起来像"2017-10-15",我希望将其转换为DatetimeOffset
(来自当前的DB服务器)。
SELECT
SWITCHOFFSET(DATEADD(mi, DATEDIFF(MI, GETDATE(), GETUTCDATE()), CAST(@DateInString + ' 00:00:00' AS DATETIMEOFFSET)), DATENAME(tzoffset, SYSDATETIMEOFFSET()))
我在这个语句中遇到了一些奇怪的问题,因为最终输出会比预期的下降+1/-1分钟。这种情况至少每10条记录/百万条就会发生一次。我试图确定这个问题,我可以看出问题是DATEDIFF()
方法返回+/-1分钟。
SELECT DATEDIFF(MI, GETDATE(), GETUTCDATE())
这应该正好返回-600(因为我的数据库服务器UTC是+10)。但是,对于少数记录,它会返回-599或601。我在存储过程中将它们作为一个select语句执行,并将其作为参数返回。
SQL如何在同一个select语句中检测到GETDATE()
和GETUTCDATE()
的两个不同日期时间值,这很奇怪。
有没有办法强制SQL在这些DATEDIFF
参数中获得完全相同的日期,或者我在这里遗漏了什么?提前感谢
我使用的是SQL Server 2014(v12.0)。
存储过程:
CREATE PROCEDURE dbo.SPConvertDateTimeOffset
@DateInString VARCHAR(10),
@DateTimeOffset_Value DATETIMEOFFSET OUTPUT,
@Datediff_Value INT OUTPUT
AS
BEGIN
-- This line returns +/- 1
SELECT @Datediff_Value = DATEDIFF(MI, GETDATE(), GETUTCDATE())
SELECT @DateTimeOffset_Value = SWITCHOFFSET(DATEADD(mi, @Datediff_Value, CAST(@DateInString + ' 00:00:00' AS DATETIMEOFFSET)), DATENAME(tzoffset, SYSDATETIMEOFFSET()))
END
@GordonLinoff解释了发生这种情况的原因:由于函数的执行时间略有不同,它们可能会返回不同的分钟。
要解决此问题,请尝试以下操作:
DECLARE @DateTimeOffset_Value Datetimeoffset
DECLARE @Datediff_Value INT, @DateInString VARCHAR( 10 )
SET @DateInString = CONVERT( VARCHAR, GETDATE(), 112 )
SET @DateTimeOffset_Value = TODATETIMEOFFSET( @DateInString, DATENAME(tzoffset,SYSDATETIMEOFFSET()))
SET @Datediff_Value = DATEDIFF( MI, @DateInString, @DateTimeOffset_Value )
SELECT @DateInString, @DateTimeOffset_Value, @Datediff_Value
它不使用当前日期比较。
注意:在日光节约更改期间,您可能会得到与预期值不同的值,具体取决于代码的运行时间。
看看https://dba.stackexchange.com/questions/28187/how-can-i-get-the-correct-offset-between-utc-and-local-times-for-a-date-that-is了解有关如何处理DTS更改的更多解决方案。
这两个函数不是同时执行的。因此,大约十万分之一的时间(在你的测试中)在一分钟边界的两侧。
如果你只是想要时区,你可以试试:
选择日期部分(tz,SYSDATETIMEOFFSET())