0

私はミリ秒Datediffの間GETDATE()で取得しようとしています。SYSDATETIME()

SELECT DATEDIFF(ms, GETDATE() , SYSDATETIME());        

私が得ている結果は0or1または2or3です。この違いの理由は何ですか?

このフィドルを参照してください

4

3 に答える 3

9

これらは、2つの異なる時間を返すことができる2つの異なる関数呼び出しです。

さらに、精度が3〜4ミリ秒しかないデータ型をGETDATE返しますが、データ型を返します。datetimeSYSDATETIME()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()以下からわかるように、関数を代入すると1回だけ呼び出されるという、もう1つの答えは正しくありません。

WHILE DATEDIFF(ms, GETDATE() , GETDATE()) = 0 
PRINT 'This will not run in an infinite loop'

Windows XPデスクトップでループを実行すると、GETDATE()SYSDATETIMEの何かが起こっている可能性があることを示す結果も表示されます。おそらく別の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 |

この不一致は大きすぎて丸めの問題にはなりません。問題はレポートする複数の行に存在するため、2つの関数の呼び出しの間に遅延があるだけのタイミングの問題ではありませんGETDATE10:16:03.26XSYSDATETIME10:16:03.250

于 2012-08-18T09:31:16.143 に答える
1

2つの関数を同時に(まったく同時に)呼び出すことはできないため、これらは異なります。実行中の他のプロセスがタイミングに影響を与える可能性があります。量を変えることによってそれらが異なる可能性がある理由は数十あります。

代わりに2回の呼び出しで同じことを行った場合GetDate()、データベースエンジンはそれらが同じものであると判断して結果を再利用できるほど賢いため、違いはありません。GetDate()ただし、との使用SysDateTime()は異なります。これは、それらが同じコードパスではないためです(異なることを行います)。

このように考えてください。とを見る1 + 21 + 2、最初の式と2番目の式が同じであることが簡単にわかります。したがって、計算を1回行うだけで済みます。とに変更する1 + Rand()1 + Rand()、2つの異なる呼び出しが何を返すかを知る方法がないRand()ため、別々に計算を行う必要があります。

于 2012-08-18T05:26:18.180 に答える
-1

この違いは、PRECISIONとRESOLUTIONの違いの良い例です(ここでは、精度を片側に残しておきましょう)。GETDATE()は、(明らかに)PRECISIONをミリ秒単位で含むDATETIMEを返しますが、タイトループに入れると、次に返される別の値が数ミリ秒後になります。RESOLUTIONは約3または4ミリ秒しかないため、毎秒約300の異なる値しか返すことができません。これについて詳しくは、こちらをご覧ください。これは、DATETIMEデータ型の設計機能/妥協点です。

于 2017-02-06T19:26:15.227 に答える