将 int 20171116101856 转换为 yyyymmddhhmmss 格式以在 datediff 函数中使用

Convert int 20171116101856 to yyyymmddhhmmss format to be used in datediff function

所以我有这个 table,它有 int 类型的日期列。

last_run_date | last_run_time
   20171116   | 100234

我正在尝试将这两个值转换为要在 datediff 语句中使用的日期时间。

这是我的声明

SELECT 1
FROM V_Jobs_All_Servers vjas
WHERE JobName='DailyReports_xxxx' and Step_Name='xxxx'
and DATEDIFF(hour, Convert(varchar,STUFF(STUFF(STUFF(STUFF(STUFF(cast(
Convert(varchar(100),vjas.last_run_date) +  Convert(varchar(100),vjas.last_run_time) as varchar)
,5,0,'-'),8,0,'-'),11,0,' '),14,0,':'),17,0,':')), Getdate()) <3

这有效,但仅当 last_run_time 值采用两位数小时格式时 101216,但只要它的一位数小时 91316 就会失败并出现以下错误,

The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.

我在 SQL Server 2005

你把这个复杂化了很多,只需用前导 0 填充你的时间值并从那里转换:

declare @t table(last_run_date int, last_run_time int);
insert into @t values(20171116,90234),(20171116,100234);

select last_run_date
      ,last_run_time
      ,convert(datetime,cast(last_run_date as nvarchar(8))
                + ' '
                + stuff(stuff(right('0' + cast(last_run_time as nvarchar(6))
                                   ,6)
                             ,5,0,':')
                       ,3,0,':')
             ,112) as DateTimeData
from @t

输出:

+---------------+---------------+-------------------------+
| last_run_date | last_run_time |      DateTimeData       |
+---------------+---------------+-------------------------+
|      20171116 |        100234 | 2017-11-16 09:02:34.000 |
|      20171116 |        100234 | 2017-11-16 10:02:34.000 |
+---------------+---------------+-------------------------+

这是一个丑陋的方式...

declare @table table (last_run_date int, last_run_time int)
insert into @table
values
(20171116,100234),
(20171116,91316)

select 
    cast(cast(cast(last_run_date as varchar) as datetime) + ' ' + stuff(stuff(last_run_time,len(last_run_time) - 1,0,':'),len(stuff(last_run_time,len(last_run_time) - 1,0,':')) - 4,0,':') as datetime)
from @table
DECLARE @temp TABLE (last_run_date int, last_run_time int)
INSERT INTO @temp VALUES (20171116, 100234)

SELECT convert(datetime,CAST(last_run_date as varchar))
             + Convert(time, Dateadd(SECOND, Right(last_run_time,2)/1
                                           ,Dateadd(MINUTE, Right(last_run_time,4)/100
                                                          ,Dateadd(hour, Right(last_run_time,6)/10000
                                                                       ,'1900-01-01'
                                                                  )
                                                    )
                                     )
                      ) [DateConverted]
  FROM @temp

产生输出:

DateConverted
2017-11-16 10:02:34.000

您可以通过单独执行每个部分来了解其工作原理。

SELECT Dateadd(hour, Right(last_run_time,6)/10000
                   ,'1900-01-01')
FROM @temp

给出小时位置。


SELECT Dateadd(MINUTE, Right(last_run_time,4)/100
                     ,Dateadd(hour, Right(last_run_time,6)/10000
                     ,'1900-01-01'))
FROM @temp

给出小时加分钟的位置。


等等

如果您从 msdb.dbo.sysjobsteps 获取此值,则有一个内置函数 msdb.dbo.agent_datetime(),可以将 last_run_datelast_run_time 转换为日期时间:

select job_id,
    step_id,
    step_name,
    msdb.dbo.agent_datetime(nullif(last_run_date,0),nullif(last_run_time,0)) as last_run_datetime
from msdb.dbo.sysjobsteps

这是一个未记录的函数。但是,至少在我的 SQL Server (2012) 版本中,该函数具有以下定义:

CREATE FUNCTION agent_datetime(@date int, @time int)
RETURNS DATETIME
AS
BEGIN
 RETURN
  (
    CONVERT(DATETIME,
          CONVERT(NVARCHAR(4),@date / 10000) + N'-' + 
          CONVERT(NVARCHAR(2),(@date % 10000)/100)  + N'-' +
          CONVERT(NVARCHAR(2),@date % 100) + N' ' +        
          CONVERT(NVARCHAR(2),@time / 10000) + N':' +        
          CONVERT(NVARCHAR(2),(@time % 10000)/100) + N':' +        
          CONVERT(NVARCHAR(2),@time % 100),
    120)
  )
END