SQL Server将十进制解析为日期时间
我在SQL Server 2017中有一个表。在此表中,日期以十进制形式存储在下一种格式中: 20180717164540.2200000 YYYYMMDDhhmiss.nnnnnnn 4位数字表示年份,2位数字表示日历月,2位数字表示一个月中的一天,2位数字表示UTC中基于24小时的一天中的一小时,2位数字表示一分钟,2位数字表示一分钟中的秒,以及分数秒 我的目标是将此格式转换为DateTime,并将其存储在数据库的另一个表中。 所以我的问题是如何在SQLServer中将此格式转换为DateTime格式。据我所知,您不能像Oracle那样创建自定义日期格式 我曾多次尝试使用格式和转换MSSQL函数,但都不起作用SQL Server将十进制解析为日期时间,sql,sql-server,database,datetime,Sql,Sql Server,Database,Datetime,我在SQL Server 2017中有一个表。在此表中,日期以十进制形式存储在下一种格式中: 20180717164540.2200000 YYYYMMDDhhmiss.nnnnnnn 4位数字表示年份,2位数字表示日历月,2位数字表示一个月中的一天,2位数字表示UTC中基于24小时的一天中的一小时,2位数字表示一分钟,2位数字表示一分钟中的秒,以及分数秒 我的目标是将此格式转换为DateTime,并将其存储在数据库的另一个表中。 所以我的问题是如何在SQLServer中将此格式转换为DateT
SELECT FORMAT(CONVERT(NVARCHAR(22), DECIMALCOLUMN), 'YYYYMMDDhhmiss') FROM SOURCE-TABLE;
谢谢你的帮助 试试这个:
DECLARE @date DECIMAL (30,7) =20180717164540.2200000
SELECT CONVERT(DATETIME, SUBSTRING(CONVERT(VARCHAR, @date),1,4) + '-' + SUBSTRING(CONVERT(VARCHAR, @date),5,2)
+ '-' + SUBSTRING(CONVERT(VARCHAR, @date),7,2) + ' ' + SUBSTRING(CONVERT(VARCHAR, @date),9,2) + ':' +
SUBSTRING(CONVERT(VARCHAR, @date),11,2) + ':' + SUBSTRING(CONVERT(VARCHAR, @date),13,2) + '.' + SUBSTRING(CONVERT(VARCHAR, @date),16,2))
您需要具有stuff()
函数的SUBSTRING()
:
很多填料
declare @dt decimal(30,8) = 20180717164540.2200000
select @dt, convert(datetime2,
stuff(
stuff(
stuff(
convert(varchar(30), @dt),
9, 0, ' '),
12, 0, ':'),
15, 0, ':')
)
/* RESULT
20180717164540.22000000 2018-07-17 16:45:40.2200000
*/
另一种方法是使用
LEFT
、SUBSTRING
和RIGHT
DECLARE @str nvarchar(22) = '20180717164540.2200000'
SELECT CONVERT(datetime2,
LEFT(@str,4)+
SUBSTRING(@str,5,2)+
SUBSTRING(@str,7,2)+' '+
SUBSTRING(@str,9,2)+':'+
SUBSTRING(@str,11,2)+':'+
SUBSTRING(@str,13,2)+'.'+
RIGHT(@str,7))
您可以填充并使用DateTime2代替DateTime:
select
cast(stuff(stuff(stuff(
cast(mydate as varchar(30)),
13,0,':'),
11,0,':'),
9,0,' ') as datetime2) as myDateTime from myTable;
你对格式的想法非常熟悉。FORMAT为您提供了一个NVARCHAR输出,您可以显式地将其转换为DATETIME2(7)(保持您的精度级别)
编辑:根据@JeroenMostert的注释将区域性参数添加到FORMAT函数。目前为止,最好的解决方案是停止存储这样的日期时间值。使用正确的数据类型,这不是问题。与使用
DATETIME
的答案不同,此解决方案不会丢失小数秒的精度。即使您的目标类型实际上是DATETIME
,而不是DATETIME2
,您也可以再次转换结果。。在这个上下文中,它的意思是VARCHAR(30)
,它恰好足够大,但依赖它是不好的形式。@jeroemoster。谢谢。我想通过明确指定en-US
作为格式中的区域性,使其稍微安全一些,因此十进制分隔符总是显示为
。否则,该代码将在(例如)SET LANGUAGE French
下失败。观察得非常好,@jeroenmoster。我编辑了答案。
DECLARE @str nvarchar(22) = '20180717164540.2200000'
SELECT CONVERT(datetime2,
LEFT(@str,4)+
SUBSTRING(@str,5,2)+
SUBSTRING(@str,7,2)+' '+
SUBSTRING(@str,9,2)+':'+
SUBSTRING(@str,11,2)+':'+
SUBSTRING(@str,13,2)+'.'+
RIGHT(@str,7))
select
cast(stuff(stuff(stuff(
cast(mydate as varchar(30)),
13,0,':'),
11,0,':'),
9,0,' ') as datetime2) as myDateTime from myTable;
DECLARE @dateWannaBe DECIMAL(21,7) = 20180717164540.2200000;
SELECT CAST(FORMAT(@dateWannaBe,'####-##-## ##:##:##.#######', 'en-US') AS DATETIME2(7)) AS ActualDateTime2;
+-----------------------------+
| ActualDateTime2 |
+-----------------------------+
| 2018-07-17 16:45:40.2200000 |
+-----------------------------+