DECLARE
@MinDelayPercent money = 0.5, -- run X% mare then the average duration
@MinDelaySeconds int = 300 -- minimum delay time =- in order to ignore short jobs delay
-- Get Running Jobs
CREATE TABLE #RunningJobs
(
Job_ID UNIQUEIDENTIFIER,
Last_Run_Date INT,
Last_Run_Time INT,
Next_Run_Date INT,
Next_Run_Time INT,
Next_Run_Schedule_ID INT,
Requested_To_Run INT,
Request_Source INT,
Request_Source_ID VARCHAR(100),
Running INT,
Current_Step INT,
Current_Retry_Attempt INT,
State INT
)
INSERT INTO #RunningJobs EXEC master.dbo.xp_sqlagent_enum_jobs 1,garbage
; with avgDrtn as
(
select h.job_id,
avg ( ( (h.run_duration % 100) -- Seconds
+ 60 * ((h.run_duration /100) % 100) -- + minutes to seconds
+ 3600 * ((h.run_duration / 10000) % 100) -- + Hours to seconds
)
) as AvgJobDuration_Seconds
from msdb.dbo.sysjobhistory h
where h.step_id = 0
group by h.job_id
)
SELECT r.Job_ID, j.name AS JobName,
msdb.dbo.agent_datetime(r.Next_Run_Date, r.Next_Run_Time) as JobStart,
DATEDIFF(second, msdb.dbo.agent_datetime(r.Next_Run_Date, r.Next_Run_Time), getdate()) as JobDuration_Seconds,
a.AvgJobDuration_Seconds
FROM #RunningJobs r
JOIN msdb.dbo.sysjobs j ON r.Job_ID=j.job_id
JOIN avgDrtn a ON j.job_id = a.job_id
WHERE -- job is still running
r.Running=1
AND -- ignore short jobs delay
( cast(DATEDIFF(second, msdb.dbo.agent_datetime(r.Next_Run_Date, r.Next_Run_Time), getdate()) as money)
-
cast(a.AvgJobDuration_Seconds as money)
) > @MinDelaySeconds
AND -- X% mare then the average duration
( cast(DATEDIFF(second, msdb.dbo.agent_datetime(r.Next_Run_Date, r.Next_Run_Time), getdate()) as money)
/
cast(a.AvgJobDuration_Seconds as money)
) > (1+@MinDelayPercent)
--ORDER BY name,next_run_date,next_run_time
DROP TABLE #RunningJobs