sql >> Databáze >  >> RDS >> Sqlserver

Proč se Datediff mezi GETDATE() a SYSDATETIME() v milisekundách vždy liší?

Jsou to dvě různá volání funkcí, která se mohou vrátit ve dvou různých časech.

Navíc GETDATE vrátí datetime datový typ, který má přesnost pouze 3–4 ms, zatímco SYSDATETIME() vrátí datetime2(7) datový typ.

I kdyby se oba hovory vrátily přesně ve stejnou dobu, mohli byste vidět problém, ke kterému dochází kvůli zaokrouhlování.

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*/

Druhá odpověď je nesprávná, pokud nahradíte v GETDATE() funkce je volána pouze jednou, jak lze demonstrovat níže.

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

Při spuštění smyčky na ploše Windows XP pomocí GETDATE() a SYSDATETIME Vidím také výsledky, které naznačují, že se může dít i něco jiného. Možná volání jiného 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 

Příklady výsledků níže

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

Řádky zájmu jsou

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

Tato nesrovnalost je příliš velká na to, aby se jednalo o problém se zaokrouhlováním, a nemůže jít pouze o problém s načasováním se zpožděním mezi voláním dvou funkcí, protože problém existuje na více než jednom řádku, který GETDATE hlásí 10:16:03.26X zatímco SYSDATETIME hlásí 10:16:03.250



  1. Všechny sloupce jsou nastaveny na stejnou hodnotu

  2. Rozdělení řetězce odděleného čárkami v PL/SQL uloženém proc

  3. Lze položky databáze přidané z položek smazat tlačítkem?

  4. Jak převedu sloupec na ASCII za běhu bez uložení, abych zkontroloval shodu s externím řetězcem ASCII?