Sql-Server

如何在 SQL Server 中將日期和時間組合到 datetime2?

  • July 29, 2019

給定以下組件

DECLARE @D DATE = '2013-10-13'
DECLARE @T TIME(7) = '23:59:59.9999999'

將它們結合起來以產生DATETIME2(7)具有價值的結果的最佳方法是什麼'2013-10-13 23:59:59.9999999'

下面列出了一些不起作用的東西**。**


SELECT @D + @T 

操作數數據類型日期對於加法運算符無效。


SELECT CAST(@D AS DATETIME2(7)) + @T 

操作數數據類型 datetime2 對 add 運算符無效。


SELECT DATEADD(NANOSECOND,DATEDIFF(NANOSECOND,CAST('00:00:00.0000000' AS TIME),@T),@D)

datediff 函式導致溢出。分隔兩個日期/時間實例的日期部分的數量太大。嘗試將 datediff 與不太精確的日期部分一起使用。

  • 在 Azure SQL 數據庫和 SQL Server 2016 中,使用DATEDIFF_BIG.

SELECT CAST(@D AS DATETIME) + @T 

數據類型 datetime 和 time 在 add 運算符中不兼容。


SELECT CAST(@D AS DATETIME) + CAST(@T AS DATETIME)

返回結果但失去精度2013-10-13 23:59:59.997

這似乎工作並保持精度:

SELECT DATEADD(day, DATEDIFF(day,'19000101',@D), CAST(@T AS DATETIME2(7)))

CASTto將值 ( )DATETIME2(7)轉換為 date 部分所在的a ,這是 date 和 datetime 類型的預設值(請參閱MSDN上的註釋*頁面。)TIME(7)``@T``DATETIME2``'1900-01-01'datetime2CAST``CONVERT

  • … 當僅表示日期或僅表示時間分量的字元數據轉換為 datetime 或 smalldatetime 數據類型時,未指定的時間分量設置為 00:00:00.000,未指定的日期分量設置為 1900-01- 01 .

DATEADD()andDATEDIFF()函式負責其餘部分,即添加 和 值 ( ) 之間的天1900-01-01DATE@D

測試:SQL-Fiddle


正如@Quandary所注意到的,上述表達式被 SQL Server 認為是不確定的。如果我們想要一個確定性表達式,比如說因為它要用於PERSISTED列,則'19000101'**需要替換為0or CONVERT(DATE, '19000101', 112)

CREATE TABLE date_time
( d DATE NOT NULL,
 t TIME(7) NOT NULL,
 dt AS DATEADD(day, 
               DATEDIFF(day, CONVERT(DATE, '19000101', 112), d), 
               CAST(t AS DATETIME2(7))
              ) PERSISTED
) ;

**:DATEDIFF(day, '19000101', d)不是確定性的,因為它對字元串的隱式轉換DATETIME以及從字元串到日期時間的轉換僅在使用特定樣式時才具有確定性。

引用自:https://dba.stackexchange.com/questions/51440