一尘不染

如何在 SQL Server 中将日期和时间组合到 datetime2?

sql-server

给定以下组件

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


阅读 128

收藏
2022-10-30

共1个答案

一尘不染

这似乎工作并保持精度:

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


正如所注意到的,上述表达式被 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
) ;
2022-10-30