我想以毫秒为单位在Datediff
和GETDATE()
之间获取SYSDATETIME()
。
SELECT DATEDIFF(ms, GETDATE() , SYSDATETIME());
我得到的结果是0
或1
或2
或3
。这种差异的原因是什么?
答案 0 :(得分:9)
它们是两个不同的函数调用,可以返回两个不同的时间。
此外GETDATE
返回datetime
数据类型,其精度仅为3-4 ms,而SYSDATETIME()
返回datetime2(7)
数据类型。
即使两个电话都返回完全相同的时间,您也可以看到由于四舍五入而遇到的问题。
DECLARE @D1 DATETIME2 = '2012-08-18 10:08:40.0650000'
DECLARE @D2 DATETIME = @D1 /*Rounded to 2012-08-18 10:08:40.067*/
SELECT DATEDIFF(ms, @D1 , @D2) /*Returns 2*/
另一个答案是错误的,如果你在GETDATE()
中替换该函数只被调用一次,如下面所示:
WHILE DATEDIFF(ms, GETDATE() , GETDATE()) = 0
PRINT 'This will not run in an infinite loop'
使用GETDATE()
和SYSDATETIME
在我的Windows XP桌面上运行循环时,我还可以看到表明其他内容可能正在进行的结果。也许调用不同的API。
CREATE TABLE #DT2
(
[D1] [DATETIME2](7),
[D2] [DATETIME2](7)
)
GO
INSERT INTO #DT2
VALUES(Getdate(), Sysdatetime())
GO 100
SELECT DISTINCT [D1],
[D2],
Datediff(MS, [D1], [D2]) AS MS
FROM #DT2
DROP TABLE #DT2
以下示例结果
+-----------------------------+-----------------------------+-----+
| D1 | D2 | MS |
+-----------------------------+-----------------------------+-----+
| 2012-08-18 10:16:03.2500000 | 2012-08-18 10:16:03.2501680 | 0 |
| 2012-08-18 10:16:03.2530000 | 2012-08-18 10:16:03.2501680 | -3 |
| 2012-08-18 10:16:03.2570000 | 2012-08-18 10:16:03.2501680 | -7 |
| 2012-08-18 10:16:03.2600000 | 2012-08-18 10:16:03.2501680 | -10 |
| 2012-08-18 10:16:03.2630000 | 2012-08-18 10:16:03.2501680 | -13 |
| 2012-08-18 10:16:03.2630000 | 2012-08-18 10:16:03.2657914 | 2 |
| 2012-08-18 10:16:03.2670000 | 2012-08-18 10:16:03.2657914 | -2 |
| 2012-08-18 10:16:03.2700000 | 2012-08-18 10:16:03.2657914 | -5 |
| 2012-08-18 10:16:03.2730000 | 2012-08-18 10:16:03.2657914 | -8 |
| 2012-08-18 10:16:03.2770000 | 2012-08-18 10:16:03.2657914 | -12 |
| 2012-08-18 10:16:03.2800000 | 2012-08-18 10:16:03.2814148 | 1 |
+-----------------------------+-----------------------------+-----+
感兴趣的行是
| 2012-08-18 10:16:03.2600000 | 2012-08-18 10:16:03.2501680 | -10 |
| 2012-08-18 10:16:03.2630000 | 2012-08-18 10:16:03.2501680 | -13 |
这种差异太大而不能成为一个舍入问题,并且不能仅仅是一个时间问题,因为问题存在于GETDATE
报告10:16:03.26X
SYSDATETIME
的多行上,因此调用这两个函数之间存在延迟} 10:16:03.250
报告{{1}}
答案 1 :(得分:1)
它们不同,因为无法同时调用这两个函数(在同一时间)。运行的其他进程可能会影响计时。他们可以根据不同的数量而有所不同。
如果你通过两次调用GetDate()
来做同样的事情,那么它们没有区别,因为数据库引擎很聪明,可以弄清楚它们是同一个东西并重新使用结果。但是,使用GetDate()
和SysDateTime()
是不同的,因为它们不是相同的代码路径(它们执行不同的操作)。
这样想:如果你看到1 + 2
和1 + 2
,很容易看出第一个表达式和第二个表达式是相同的,所以你只需要这样做计算一次。如果您将其更改为1 + Rand()
和1 + Rand()
,则无法知道对Rand()
的两次不同调用将返回什么,因此您必须单独进行计算。
答案 2 :(得分:-1)
这种差异是PRECISION和RESOLUTION之间差异的一个很好的例子(让我们暂时将ACCURACY留给一方)。 GETDATE()返回一个带有(显然)PRECISION的DATETIME到毫秒,但是,如果你把它放在一个紧密的循环中,你会发现返回的下一个不同的值是几毫秒之后;它每秒只能返回大约300个不同的值,因为它的分辨率只有大约3或4毫秒。 read more about this here这是DATETIME数据类型的设计特性/折衷方案。