在 SQL Server 数据库中将长日期时间转换为实际日期时间的最佳方法是啥?

Posted

技术标签:

【中文标题】在 SQL Server 数据库中将长日期时间转换为实际日期时间的最佳方法是啥?【英文标题】:What is the best way to convert a long datetime into an actual datetime in a SQL Server database?在 SQL Server 数据库中将长日期时间转换为实际日期时间的最佳方法是什么? 【发布时间】:2021-10-26 12:45:11 【问题描述】:

在我的 Microsoft SQL Server 数据库中,每个日期或日期时间都表示为 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)

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

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

【问题讨论】:

长期修复设计,纠正所有列,才是真正的答案。 明智地使用/% 可用于提取元素,同时停留在数字领域,而不是“字符串输入”然后DATETIME2FROMPARTS 可能是你的朋友。 “更好”是什么意思? 更好的性能 = 正确存储数据(可能在您的 ERP 中的附加表中)。通常,更少的代码 = 代码高尔夫。你可以在不更好的情况下做出真正简洁的东西,除了字符数方面,这对大多数人来说远没有清晰度那么有价值。 要添加到@AaronBertrand 的评论中,您还可以编写非常短的代码,但是远非高性能。例如,WHILE 可能是编写执行某些操作的逻辑的一种非常短的方法(例如,将分隔的字符串拆分为行),但是,它的性能远低于基于解决方案集的解决方案或创建一个CLR 函数。更短!= 更快。 【参考方案1】:

您可以在没有强制转换和字符串函数的情况下使用 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 
)

【讨论】:

【参考方案2】:

一种方法是使用一组简单的子字符串提取部分。鉴于此表和数据:

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
示例db<>fiddle

【讨论】:

以上是关于在 SQL Server 数据库中将长日期时间转换为实际日期时间的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP Laravel 中的 SQL Server 中将字符串转换为日期数据类型

在sql server中将日期时间转换为yyyymmddhhmmss

在 SQL Server 中将字符串转换为日期

在函数 SQL Server 中将字符串转换为日期时间

在 MS SQL Server 中将字符串转换为日期时间

在 C# 中将十六进制值从 SQL Server 转换为日期时间