两个日期之间的SQL Server DateDiff返回不准确的值
我想通过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
@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。
我仍然试图从MSDN中找到任何引用/链接,以便GetDate()和GetUTCD在单选时返回不同的日期时间。但是,这个答案解决了我将日期转换为datetimeoffset的问题。谢谢。 – Bharathi
@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
两个功能不会被同时执行。所以大概有一次100,000(在你的测试中)时间是在分钟边界的两边。
如果你只是想的时区,你可以尝试:
选择日期部分(TZ,SYSDATETIMEOFFSET())
如果你这么做很多次,那么'getdate()'和'getutcdate()'可能会关闭几毫秒。 –
真的很重要吗?因为,我只为Minutes部分获得了datediff。即使我做了几次,理想情况下它应该给我相同的日期时间值。但是,如果我多次使用它,为什么它在毫秒数上有差异,您有任何参考吗? – Bharathi
它可能很重要,因为'datediff()'测量时间之间的界限*。 –