3

I have to make a manual calculation of the next run date for a job, can you help me?

Francisco
  • 31
  • 1
  • 1
  • 2
  • (please don't double-post; be patient) – Marc Gravell Mar 08 '10 at 05:25
  • (additional detail excised from duplicate): "I have to manually calculate the value of next_run_date based on freq_interval, freq_subday_type, freq_subday_interval, freq_relative_interval, freq_recurrence_factor, etc" – Marc Gravell Mar 08 '10 at 05:26

4 Answers4

6

to get the next run date for a job you can use then sysschedules and sysjobschedules tables

check the next_run_date and next_runtime columns from the table sysjobschedules

next_run_date int Next date on which the job is scheduled to run. The date is formatted YYYYMMDD.

next_run_time int Time at which the job is scheduled to run. The time is formatted HHMMSS, and uses a 24-hour clock.

see this script

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

or you can use the msdb.dbo.sp_help_jobschedule stored procedure, to get the same info.

UPDATE

if you need calculate manually the next_run_date you must check the sysschedules table and see the freq_interval, freq_subday_type, freq_subday_interval, freq_relative_interval, freq_recurrence_factor, active_start_date, active_start_time columns to determine the formula.

check this link to see an example of use.

RRUZ
  • 134,889
  • 20
  • 356
  • 483
3

Check this one:

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 
Sergey Glotov
  • 20,200
  • 11
  • 84
  • 98
Sukhomoy
  • 31
  • 1
0

The short answer is that there's no single formula - it varies by value of freq_type.

The site seems to be down at the moment of writing, but there is an article at http://www.sqlmag.com/Article/ArticleID/99593/sql_server_99593.html which covers how to derive this information. Unfortunately, the site doesn't allow Google to cache its content, so it can't be retrieved until the site comes back up

This looks like a decent alternative source for the kind of query you're trying to write.

Ed Harper
  • 21,127
  • 4
  • 54
  • 80
0

here is a very nice script where you can get the next run date.

-- 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];
Marcello Miorelli
  • 3,368
  • 4
  • 44
  • 67