在 SQL 服务器数据库中将长日期时间转换为实际日期时间的最佳方法是什么?

What is the best way to convert a long datetime into an actual datetime in a SQL Server database?

在我的 Microsoft SQL 服务器数据库中,每个日期或日期时间都表示为一个 decimal(17,0) 值。

例如:20210722054500000 将转换为 2021-07-22 05:45:00:000

我已经想出了一个解决方案来转换它:

SELECT 
    CONVERT(datetime, (SUBSTRING(CAST(20210722054500000 AS varchar(20)), 1, 4) + '-' + 
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 5, 2) + '-' + 
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 7, 2) + ' ' + 
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 9, 2) + ':' + 
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 11, 2) + ':00'), 120)

它有效,但我觉得应该有更好的解决方案来转换它。

所以我的问题是有没有人有一种方法需要更少的代码或者在性能方面会更好?

一种方法是使用一组简单的子字符串来提取零件。鉴于此 table 和数据:

CREATE TABLE dbo.WhoDesignedThis
(
  Id int,
  TheDate decimal(17,0) -- this was hard to write with a straight face
);

INSERT dbo.WhoDesignedThis(Id, TheDate) VALUES
(1, 20210722054500000),
(2, 19991231132247699);

这个查询:

;WITH x AS
(
  SELECT Id, TheDate, x = CONVERT(char(17), TheDate) 
  FROM dbo.WhoDesignedThis
)
SELECT Id, TheDate, output = DATETIMEFROMPARTS
  (
    LEFT(x,4), 
    SUBSTRING(x,5,2), 
    SUBSTRING(x,7,2), 
    SUBSTRING(x,9,2), 
    SUBSTRING(x,11,2), 
    SUBSTRING(x,13,2), 
    RIGHT(x,3)
  )
FROM x;

产生这些结果:

Id TheDate output
1 20210722054500000 2021-07-22 05:45:00.000
2 19991231132247699 1999-12-31 13:22:47.700

您可以在没有强制转换和字符串函数的情况下使用 datetimefromparts:

declare @input decimal(17,0) = 20210722054500000
select DATETIMEFROMPARTS(
    @input/10000000000000      ,-- year
    @input/100000000000 % 100  ,-- month
    @input/1000000000 % 100    ,-- day
    @input/10000000 % 100      ,-- hour
    @input/100000%100          ,-- minute
    @input/1000%100            ,-- seconds
    @input%1000                -- milliseconds 
)