Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在TSQL中从Varchar到Datetime_Sql_Sql Server_Tsql_Type Conversion - Fatal编程技术网

在TSQL中从Varchar到Datetime

在TSQL中从Varchar到Datetime,sql,sql-server,tsql,type-conversion,Sql,Sql Server,Tsql,Type Conversion,如何转换存储的日期和时间值 20200406151341 截止日期时间值2020/04/06 15:31:41 YYYY/MM/DD HH:MM:SS.000?我无法找到合适的转换格式,到目前为止,唯一的方法是像下面这样解析VARCHAR select dateadd(second, cast(substring('20200406151341',13,2) as int),dateadd(minute, cast(substring('20200406151341',11,2) as int)

如何转换存储的日期和时间值

20200406151341

截止日期时间值2020/04/06 15:31:41 YYYY/MM/DD HH:MM:SS.000?我无法找到合适的转换格式,到目前为止,唯一的方法是像下面这样解析VARCHAR

select dateadd(second, cast(substring('20200406151341',13,2) as int),dateadd(minute, cast(substring('20200406151341',11,2) as int), dateadd(hour,cast(substring('20200406151341',9,2) as int),convert(datetime, left('20200406151341',8), 112)))).
它可以工作,但很难阅读和理解,特别是当我必须在SELECT语句中多次使用它时

此外,我还感到惊讶的是,上面转换的查询速度与直接以DATETIME格式存储日期的查询速度一样快。MSSQL服务器是否使用某种缓存,因此每行只需执行一次转换


我使用的是MSSQL Server 2016。

我认为没有一种内置的简单方法可以做到这一点

你不必到几秒钟就可以做到这一点。您可以轻松地将前8个字符转换为日期。通过一些字符串操作,您可以将最后六个转换为时间,然后将时间添加为日期时间值:

您也可以使用算术而不是3个日期相加:

注意:这与您的版本一样使用从字符串到整数的隐式转换。

您可以使用stuff:


让我们在组合中加入更多选项:

DECLARE @StrDate varchar(14) = '20200406151341'

SELECT  DATETIMEFROMPARTS(
            LEFT(@StrDate, 4), -- year
            SUBSTRING(@StrDate, 5, 2), -- month
            SUBSTRING(@StrDate, 7, 2), -- day
            SUBSTRING(@StrDate, 9, 2), -- hour
            SUBSTRING(@StrDate, 11, 2), -- minute
            SUBSTRING(@StrDate, 13, 2), -- second
            0 -- millisecond
        ) As [Using DateTimeFromParst],

        CONVERT(DateTime, LEFT(@StrDate, 8), 112) + -- Date
        CONVERT(DateTime, STUFF(STUFF(RIGHT(@StrDate, 6), 5, 0, ':'), 3, 0, ':'), 114) -- Time
        As [Using convert and stuff]
结果:

Using DateTimeFromParst     Using convert and stuff
2020-04-06 15:13:41         2020-04-06 15:13:41
我建议在字符串无效的情况下使用or,如果无效,它们将返回NULL而不是引发错误。有关这些功能的更多详细信息,请参阅链接

declare @val varchar(20) 
set @val = '20200416151341'

select try_convert(datetime, 
           stuff(stuff(stuff(stuff(@val, 9, 0, ' '), 10, 0, ''), 12, 0, ':'), 15, 0, ':')
              );


select try_cast(
           stuff(stuff(stuff(stuff(@val, 9, 0, ' '), 10, 0, ''), 12, 0, ':'), 15, 0, ':')
              as datetime);

保留子字符串,但将它们放在一个文件夹中。我很惊讶上面转换的查询速度如此之快——在找到行之后,在最终选择中计算标量的速度非常快。最好的方法是使用datatime数据类型存储datetime值。如果您不能更改结构,那么我建议在表中创建一个计算列,或者使用视图,并准备好处理无法转换的值。这就是当模式没有被考虑太多的时候会发生的事情。谢谢你,这是一个好办法,我也喜欢算术版本
DECLARE @StrDate varchar(14) = '20200406151341'

SELECT  DATETIMEFROMPARTS(
            LEFT(@StrDate, 4), -- year
            SUBSTRING(@StrDate, 5, 2), -- month
            SUBSTRING(@StrDate, 7, 2), -- day
            SUBSTRING(@StrDate, 9, 2), -- hour
            SUBSTRING(@StrDate, 11, 2), -- minute
            SUBSTRING(@StrDate, 13, 2), -- second
            0 -- millisecond
        ) As [Using DateTimeFromParst],

        CONVERT(DateTime, LEFT(@StrDate, 8), 112) + -- Date
        CONVERT(DateTime, STUFF(STUFF(RIGHT(@StrDate, 6), 5, 0, ':'), 3, 0, ':'), 114) -- Time
        As [Using convert and stuff]
Using DateTimeFromParst     Using convert and stuff
2020-04-06 15:13:41         2020-04-06 15:13:41
declare @val varchar(20) 
set @val = '20200416151341'

select try_convert(datetime, 
           stuff(stuff(stuff(stuff(@val, 9, 0, ' '), 10, 0, ''), 12, 0, ':'), 15, 0, ':')
              );


select try_cast(
           stuff(stuff(stuff(stuff(@val, 9, 0, ' '), 10, 0, ''), 12, 0, ':'), 15, 0, ':')
              as datetime);