2017-10-16 76 views
2

我想通过ETL作业将字符串转换为DateTimeOffset(在SQL Server中)。基本上,我的字符串看起来像'2017-10-15',我希望将其转换为DatetimeOffset(来自当前的数据库服务器)。两个日期之间的SQL Server DateDiff返回不准确的值

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 
+0

如果你这么做很多次,那么'getdate()'和'getutcdate()'可能会关闭几毫秒。 –

+0

真的很重要吗?因为,我只为Minutes部分获得了datediff。即使我做了几次,理想情况下它应该给我相同的日期时间值。但是,如果我多次使用它,为什么它在毫秒数上有差异,您有任何参考吗? – Bharathi

+3

它可能很重要,因为'datediff()'测量时间之间的界限*。 –

回答

0

@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 

它不使用当前的日期比较。

备注:在白天节电改变期间,您可能会得到与预期值不同的值,具体取决于代码的运行时间。

有关如何处理DTS更改的更多解决方案,请参阅https://dba.stackexchange.com/questions/28187/how-can-i-get-the-correct-offset-between-utc-and-local-times-for-a-date-that-is

+0

我仍然试图从MSDN中找到任何引用/链接,以便GetDate()和GetUTCD在单选时返回不同的日期时间。但是,这个答案解决了我将日期转换为datetimeoffset的问题。谢谢。 – Bharathi

+1

@Bharathi - 我找不到任何微软引用,但有一些存在的问题处理相同的问题:https://stackoverflow.com/questions/6036223/will-getutcdate-return-the-same-value- if-used-in-the-same-statement/6036783#6036783和https://stackoverflow.com/questions/3620105/sql-server-intrigued-by-getdate/3620119#3620119 – Alex

0

两个功能不会被同时执行。所以大概有一次100,000(在你的测试中)时间是在分钟边界的两边。

如果你只是想的时区,你可以尝试:

选择日期部分(TZ,SYSDATETIMEOFFSET())

相关问题