SQL如何为作业计划计算NEXT_RUN_DATE?

时间:2010-03-08 02:13:06

标签: sql sql-server sql-server-agent

我必须手工计算一份工作的下一个运行日期,你能帮助我吗?

4 个答案:

答案 0 :(得分:6)

获取您可以使用的作业的下一个运行日期,然后sysschedulessysjobschedules

检查表sysjobschedules

中的next_run_date和next_runtime列
  

next_run_date int下一个日期   该工作计划运行。日期   格式为YYYYMMDD。

     

next_run_time int时间   工作计划运行。现在的时间是   格式化HHMMSS,并使用24小时   时钟。

查看此脚本

Select sched.*,jobsched.* FROM msdb.dbo.sysschedules AS sched
inner Join msdb.dbo.sysjobschedules AS jobsched ON sched.schedule_id = jobsched.schedule_id

或者您可以使用msdb.dbo.sp_help_jobschedule存储过程来获取相同的信息。

<强>更新

如果需要手动计算next_run_date,则必须检查sysschedules表并查看freq_interval,freq_subday_type,freq_subday_interval,freq_relative_interval,freq_recurrence_factor,active_start_date,active_start_time列以确定公式。

检查此link以查看使用示例。

答案 1 :(得分:2)

检查一下:

SELECT 

    J.NAME JOB, 

    DATEADD(SS,(H.RUN_TIME)%100,DATEADD(N,(H.RUN_TIME/100)%100,DATEADD(HH,H.RUN_TIME/10000,CONVERT(DATETIME,CONVERT(VARCHAR(8),H.RUN_DATE),112))))
    JOB_STARTED,  

    DATEADD(SS,((H.RUN_DURATION)%10000)%100,DATEADD(N,((H.RUN_DURATION)%10000)/100,DATEADD(HH,(H.RUN_DURATION)/10000,DATEADD(SS,(H.RUN_TIME)%100,DATEADD(N,(H.RUN_TIME/100)%100,DATEADD(HH,H.RUN_TIME/10000,CONVERT(DATETIME,CONVERT(VARCHAR(8),H.RUN_DATE),112)))))))
    JOB_COMPLETED,  

    CONVERT(VARCHAR(2),(H.RUN_DURATION)/10000) + ':' + 
    CONVERT(VARCHAR(2),((H.RUN_DURATION)%10000)/100)+ ':' + 
    CONVERT(VARCHAR(2),((H.RUN_DURATION)%10000)%100) RUN_DURATION,

    CASE H.RUN_STATUS 
    WHEN 0 THEN 'FAILED'
    WHEN 1 THEN 'SUCCEEDED'
    WHEN 2 THEN 'RETRY'
    WHEN 3 THEN 'CANCELED'
    WHEN 4 THEN 'IN PROGRESS'
    END RUN_STATUS
    ,CASE S.FREQ_TYPE 
    WHEN  1 THEN 'ONCE'
    WHEN  4 THEN ' DAILY'
    WHEN  8 THEN ' WEEKLY'
    WHEN  16 THEN ' MONTHLY'
    WHEN  32 THEN ' MONTHLY RELATIVE'
    WHEN  64 THEN ' WHEN SQL SERVER'
    ELSE 'N/A' END [FREQ]
    ,CASE 
    WHEN S.NEXT_RUN_DATE > 0 THEN DATEADD(N,(NEXT_RUN_TIME%10000)/100,DATEADD(HH,NEXT_RUN_TIME/10000,CONVERT(DATETIME,CONVERT(VARCHAR(8),NEXT_RUN_DATE),112)))  
    ELSE CONVERT(DATETIME,CONVERT(VARCHAR(8),'19000101'),112) END NEXT_RUN

FROM 

    MSDB..SYSJOBHISTORY H,
    MSDB..SYSJOBS J, 
    MSDB..SYSJOBSCHEDULES S,
    (
    SELECT 
            MAX(INSTANCE_ID) INSTANCE_ID
            ,JOB_ID 
    FROM MSDB..SYSJOBHISTORY GROUP BY JOB_ID
    ) M
WHERE 
    H.JOB_ID = J.JOB_ID 
AND 
    J.JOB_ID = S.JOB_ID 
AND 
    H.JOB_ID = M.JOB_ID 
AND 
    H.INSTANCE_ID = M.INSTANCE_ID

-- IF you want to check all job for today then uncomments below

-- AND 

--     RUN_DATE = (YEAR(GETDATE())*10000) + (MONTH(GETDATE()) * 100) + DAY(GETDATE())
ORDER BY NEXT_RUN 

答案 2 :(得分:0)

简短的回答是,没有单一的公式 - 它取决于freq_type的值。

该网站在撰写本文时似乎已经失效,但http://www.sqlmag.com/Article/ArticleID/99593/sql_server_99593.html上有一篇文章介绍了如何获取这些信息。遗憾的是,该网站不允许Google缓存其内容,因此在网站重新启动之前无法检索

This看起来像是您尝试撰写的查询类型的一个不错的替代来源。

答案 3 :(得分:0)

here是一个非常好的脚本,您可以在其中获得下一个运行日期。

-- http://www.sqlprofessionals.com/blog/sql-scripts/2014/10/06/insight-into-sql-agent-job-schedules/

SELECT   [JobName] = [jobs].[name]
        ,[Enabled] = CASE [jobs].[enabled] WHEN 1 THEN 'Yes' ELSE 'No' END
        ,[Scheduled] = CASE [schedule].[enabled] WHEN 1 THEN 'Yes' ELSE 'No' END

        ,[Next_Run_Date] = 
                CASE [jobschedule].[next_run_date]
                    WHEN 0 THEN CONVERT(DATETIME, '1900/1/1')
                    ELSE CONVERT(DATETIME, CONVERT(CHAR(8), [jobschedule].[next_run_date], 112) + ' ' + 
                         STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [jobschedule].[next_run_time]), 6), 5, 0, ':'), 3, 0, ':'))
                END

        ,[Category] = [categories].[name]
        ,[Owner] = SUSER_SNAME([jobs].[owner_sid])

        ,[Description] = [jobs].[description]
        ,[Occurs] = 
                CASE [schedule].[freq_type]
                    WHEN   1 THEN 'Once'
                    WHEN   4 THEN 'Daily'
                    WHEN   8 THEN 'Weekly'
                    WHEN  16 THEN 'Monthly'
                    WHEN  32 THEN 'Monthly relative'
                    WHEN  64 THEN 'When SQL Server Agent starts'
                    WHEN 128 THEN 'Start whenever the CPU(s) become idle' 
                    ELSE ''
                END
        ,[Occurs_detail] = 
                CASE [schedule].[freq_type]
                    WHEN   1 THEN 'O'
                    WHEN   4 THEN 'Every ' + CONVERT(VARCHAR, [schedule].[freq_interval]) + ' day(s)'
                    WHEN   8 THEN 'Every ' + CONVERT(VARCHAR, [schedule].[freq_recurrence_factor]) + ' weeks(s) on ' + 
                        LEFT(
                            CASE WHEN [schedule].[freq_interval] &  1 =  1 THEN 'Sunday, '    ELSE '' END + 
                            CASE WHEN [schedule].[freq_interval] &  2 =  2 THEN 'Monday, '    ELSE '' END + 
                            CASE WHEN [schedule].[freq_interval] &  4 =  4 THEN 'Tuesday, '   ELSE '' END + 
                            CASE WHEN [schedule].[freq_interval] &  8 =  8 THEN 'Wednesday, ' ELSE '' END + 
                            CASE WHEN [schedule].[freq_interval] & 16 = 16 THEN 'Thursday, '  ELSE '' END + 
                            CASE WHEN [schedule].[freq_interval] & 32 = 32 THEN 'Friday, '    ELSE '' END + 
                            CASE WHEN [schedule].[freq_interval] & 64 = 64 THEN 'Saturday, '  ELSE '' END , 
                            LEN(
                                CASE WHEN [schedule].[freq_interval] &  1 =  1 THEN 'Sunday, '    ELSE '' END + 
                                CASE WHEN [schedule].[freq_interval] &  2 =  2 THEN 'Monday, '    ELSE '' END + 
                                CASE WHEN [schedule].[freq_interval] &  4 =  4 THEN 'Tuesday, '   ELSE '' END + 
                                CASE WHEN [schedule].[freq_interval] &  8 =  8 THEN 'Wednesday, ' ELSE '' END + 
                                CASE WHEN [schedule].[freq_interval] & 16 = 16 THEN 'Thursday, '  ELSE '' END + 
                                CASE WHEN [schedule].[freq_interval] & 32 = 32 THEN 'Friday, '    ELSE '' END + 
                                CASE WHEN [schedule].[freq_interval] & 64 = 64 THEN 'Saturday, '  ELSE '' END 
                            ) - 1
                        )
                    WHEN  16 THEN 'Day ' + CONVERT(VARCHAR, [schedule].[freq_interval]) + ' of every ' + CONVERT(VARCHAR, [schedule].[freq_recurrence_factor]) + ' month(s)'
                    WHEN  32 THEN 'The ' + 
                            CASE [schedule].[freq_relative_interval]
                                WHEN  1 THEN 'First'
                                WHEN  2 THEN 'Second'
                                WHEN  4 THEN 'Third'
                                WHEN  8 THEN 'Fourth'
                                WHEN 16 THEN 'Last' 
                            END +
                            CASE [schedule].[freq_interval]
                                WHEN  1 THEN ' Sunday'
                                WHEN  2 THEN ' Monday'
                                WHEN  3 THEN ' Tuesday'
                                WHEN  4 THEN ' Wednesday'
                                WHEN  5 THEN ' Thursday'
                                WHEN  6 THEN ' Friday'
                                WHEN  7 THEN ' Saturday'
                                WHEN  8 THEN ' Day'
                                WHEN  9 THEN ' Weekday'
                                WHEN 10 THEN ' Weekend Day' 
                            END + ' of every ' + CONVERT(VARCHAR, [schedule].[freq_recurrence_factor]) + ' month(s)' 
                    ELSE ''
                END
        ,[Frequency] = 
                CASE [schedule].[freq_subday_type]
                    WHEN 1 THEN 'Occurs once at ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':')
                    WHEN 2 THEN 'Occurs every ' + 
                                CONVERT(VARCHAR, [schedule].[freq_subday_interval]) + ' Seconds(s) between ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':') + ' and ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_end_time]), 6), 5, 0, ':'), 3, 0, ':')
                    WHEN 4 THEN 'Occurs every ' + 
                                CONVERT(VARCHAR, [schedule].[freq_subday_interval]) + ' Minute(s) between ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':') + ' and ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_end_time]), 6), 5, 0, ':'), 3, 0, ':')
                    WHEN 8 THEN 'Occurs every ' + 
                                CONVERT(VARCHAR, [schedule].[freq_subday_interval]) + ' Hour(s) between ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_start_time]), 6), 5, 0, ':'), 3, 0, ':') + ' and ' + 
                                STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), [schedule].[active_end_time]), 6), 5, 0, ':'), 3, 0, ':')
                    ELSE ''
                END
        ,[AvgDurationInSec] = CONVERT(DECIMAL(10, 2), [jobhistory].[AvgDuration])

FROM     [msdb].[dbo].[sysjobs] AS [jobs] WITh(NOLOCK) 
         LEFT OUTER JOIN [msdb].[dbo].[sysjobschedules] AS [jobschedule] WITh(NOLOCK) 
                 ON [jobs].[job_id] = [jobschedule].[job_id] 
         LEFT OUTER JOIN [msdb].[dbo].[sysschedules] AS [schedule] WITh(NOLOCK) 
                 ON [jobschedule].[schedule_id] = [schedule].[schedule_id] 
         INNER JOIN [msdb].[dbo].[syscategories] [categories] WITh(NOLOCK) 
                 ON [jobs].[category_id] = [categories].[category_id] 
         LEFT OUTER JOIN 
                    (   SELECT   [job_id], [AvgDuration] = (SUM((([run_duration] / 10000 * 3600) + 
                                                                (([run_duration] % 10000) / 100 * 60) + 
                                                                 ([run_duration] % 10000) % 100)) * 1.0) / COUNT([job_id])
                        FROM     [msdb].[dbo].[sysjobhistory] WITh(NOLOCK)
                        WHERE    [step_id] = 0 
                        GROUP BY [job_id]
                     ) AS [jobhistory] 
                 ON [jobhistory].[job_id] = [jobs].[job_id];