2010-03-08 118 views
1

我必须手工计算下一次工作的日期,你能帮助我吗?SQL如何计算NEXT_RUN_DATE作业计划?

+0

(请不要双击后,耐心等待) – 2010-03-08 05:25:57

+0

(由重复的额外细节切除):“我必须手动计算next_run_date的基础上freq_interval的,的freq_subday_type,freq_subday_interval,freq_relative_interval,freq_recurrence_factor等价值“ – 2010-03-08 05:26:54

回答

6

得到一份工作下次运行日期,你可以使用然后sysschedulessysjobschedules

检查next_run_date和next_runtime列从表sysjobschedules

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存储过程,得到相同的信息。

UPDATE

如果你需要计算手动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

是的,但SQL如何计算NEXT_RUN_DATE的值? – Francisco 2010-03-08 03:46:24

+1

你知道配方吗? 这就是问题所在。 在此先感谢。 – Francisco 2010-03-08 05:12:20

0

简单的答案是没有单个公式 - 它随freq_type的值而变化。

该网站似乎在撰写的时候已关闭,但有一篇文章在http://www.sqlmag.com/Article/ArticleID/99593/sql_server_99593.html,其中介绍了如何导出此信息。不幸的是,该网站不允许谷歌缓存其内容,所以它不能被检索,直到该网站恢复为止

This看起来像一个体面的替代来源,你试图编写的查询类型。

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 
+0

运行此脚本时出现错误。 s.freq_type? – 2016-09-20 16:14:28

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];