我正在寻找一种将iso 8601
转换为20120503-56320
格式的方法。这是我要转换的值的示例:
CONVERT(NVARCHAR(30), ia.alcreateStamp, 126)
我已经尝试过:
{{1}}
这不会更改格式。先感谢您。
贝斯
答案 0 :(得分:3)
这里的第一个问题是您将日期时间存储为(n)varchar
。按日期存储日期和时间date
,time
或datetime(2)
。
使用CONVERT
将数据类型更改为(n)varchar
时,提供样式代码可以告诉数据引擎字符串应来自相应数据类型的格式(在这种情况下为{{1} }或date
数据类型)。您正在将datetime(2)
转换为nvarchar
,因此样式代码将被完全忽略。
我 猜测 ,值nvarchar
是日期2012-05-03 15:34:40(一天中有86400秒,而我假设-56320是一天中的秒数),因此要将您的值转换为20120503-56320
,您可以使用:
datetime2
老实说,此时,您应该停下来。将SELECT DateString,
DATEADD(SECOND,CONVERT(int,RIGHT(V.DateString,LEN(V.DateString) - CI.I)),CONVERT(datetime2(0),LEFT(V.DateString,CI.I -1))),
CONVERT(varchar(19),DATEADD(SECOND,CONVERT(int,RIGHT(V.DateString,LEN(V.DateString) - CI.I)),CONVERT(datetime2(0),LEFT(V.DateString,CI.I -1))),126)
FROM (VALUES('20120503-56320')) V(DateString)
CROSS APPLY (VALUES(CHARINDEX('-',V.DateString))) CI(I);
值传递到您的表示层并在那里处理格式。
但是,如果您确实要改进,请修复数据类型。一种方法可能是添加一个新的持久列:
datetime2
答案 1 :(得分:1)
这假定格式为YYYYMMDD-,后接午夜以来的秒数。
您可以通过在日期值上添加秒来构造所需的值:
select dateadd(second, convert(int, right(str, 5)), convert(datetime, left(str, 8)))
from (values ('20120503-56320')) v(str)
这假定秒是零填充的,所以“ 1”将是“ -00001”。如果不是这种情况,请使用:
select dateadd(second, convert(int, stuff(str, 1, charindex('-', str) , '')), convert(datetime, left(str, 8)))
或者(如Jeroen指出的那样):
select dateadd(second, convert(int, stuff(str, 1, 9, '')), convert(datetime, left(str, 8)))
您也可以将其作为生成的列直接合并到表中:
alter table t add alcreateStamp_dt as
( dateadd(second, convert(int, stuff(str, 1, charindex('-', str) , '')), convert(datetime, left(str, 8))) );
然后,您不需要每次将值设为datetime
时都复制逻辑。