VIVEKANANDHAN_PERIASAMY
asked on
Need to restart the SQL job if it's running morethan 30 minutes
Hello,
I have a SQL job called "ALL - DelHistory" which occupationally gets hung or running morethan 30 minutes.In that case,it should stop the job,wait for 5 minutes and should start the job again.
I have created a another sql job to montior ALL-DelHistory job, but script below is not working.Please modify the script to achieve my goal.
I have a SQL job called "ALL - DelHistory" which occupationally gets hung or running morethan 30 minutes.In that case,it should stop the job,wait for 5 minutes and should start the job again.
I have created a another sql job to montior ALL-DelHistory job, but script below is not working.Please modify the script to achieve my goal.
USE [msdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Monitoring_all_del_history_job] (
@threshold_minute int = 30, -- Default is set to 30 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL -- '<ExcludeJob><JobName JOB="Export TMF PerfData"/></ExcludeJob>'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner sysname
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1
AND j.name ='ALL - DelHistory' --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND start_execution_date = @JobStartTime)
IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
waitfor delay '00:05:00'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
END
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
ASKER
No Sir,
Even if this job running for morethan 30 minutes, it's not stopping and restart the job.
I'm i missing anything in sp's.
Even if this job running for morethan 30 minutes, it's not stopping and restart the job.
I'm i missing anything in sp's.
Hi,
Please find my comment ID: 38069283 in https://www.experts-exchange.com/questions/27732791/Need-a-double-monitoring-for-SQL-job's.html?cid=1752
Here's the code:
Please find my comment ID: 38069283 in https://www.experts-exchange.com/questions/27732791/Need-a-double-monitoring-for-SQL-job's.html?cid=1752
Here's the code:
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL, -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company.com'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:11pt;} ' +
'</style>' +
'</head>' +
'<body>'
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
SET @TableTail = '</table></body></html>';
SET @Table_Content = @TableHead+'<table cellpadding=0 cellspacing=0 border=0>' +
'<tr bgcolor=#FFEFD8><td align=center><b>Job Name</b></td>' +
'<td align=center><b>Last Run Date</b></td>' +
'<td align=center><b>Last Run Time</b></td>' +
'<td align=center><b>Next Run Date</b></td>' +
'<td align=center><b>Next Run Time</b></td>' +
'<td align=center><b>Next Run Time</b></td>' +
'<td align=center><b>Running</b></td>' +
'<td align=center><b>Current Step</b></td>' +
'<td align=center><b>Current Rettry Attempt</b></td>' +
'<td align=center><b>Job State</b></td></tr>'
SELECT @Body = (SELECT ROW_NUMBER() OVER(ORDER BY job_id) % 2 AS [TRRow],
job_id AS [TD],
last_run_date AS [TD],
last_run_time AS [TD],
next_run_date AS [TD],
next_run_time AS [TD],
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS [TD],
current_step AS [TD],
current_retry_attempt AS [TD],
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS [TD]
FROM #xp_results_new
FOR XML RAW('tr'), ELEMENTS)
SET @Body = Replace(@Body, '_x0020_', space(1))
SET @Body = Replace(@Body, '_x003D_', '=')
SET @Body = Replace(@Body, '<tr><TRRow>1</TRRow>', '<tr bgcolor=#C6CFFF>')
SET @Body = Replace(@Body, '<TRRow>0</TRRow>', '')
SELECT @Body = @TableHead + @Body + @TableTail
SET @mail_subject = '[!!!WARNING!!!] Job'+ISNULL(@JobName,'UNKNOWN')+' is running longer than 30 minutes'
EXEC msdb.dbo.sp_send_dbmail
@recipients=@mail_recipients,
@subject = @mail_subject,
@body = @Body,
@body_format = 'HTML' ;
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END
END
END
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
ASKER
Thanks Sir, Can you please explain the code Sir. Willing to learn the code.Awesome work.
I have to test it.I have one more doubt.
Will script will take of sending the mail to the appropriate recipients
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company .com'
or should need to configure any operator or enable database mail?Because by default all are disabled in our environment.
I have to test it.I have one more doubt.
Will script will take of sending the mail to the appropriate recipients
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company
or should need to configure any operator or enable database mail?Because by default all are disabled in our environment.
Dear Vivekanandhan,
Please edit code to fulfill your requirements. I've added some values to show you how it should be configured. You can edit @mail_recipients VARCHAR(512)='test@company .com'
to your default recipients list. While you're executing procedure you suply this parameter with value, default one will be ignored. NULL value for mail profile name means that sp_send_dbmail procedure will use default mail profile for user executing code.
E.g.
EXECUTE [dbo].[SQL_Job_Monitor] @mail_profile='Name of your mail profile', @mail_recipients='List of recipients'
EXECUTE [dbo].[SQL_Job_Monitor] @mail_profile='Jobs_profil e', @mail_recipients='Vivekana ndhan.Peri asamy@ee.c om;Someone .Else@mail address.co m'
Please edit code to fulfill your requirements. I've added some values to show you how it should be configured. You can edit @mail_recipients VARCHAR(512)='test@company
to your default recipients list. While you're executing procedure you suply this parameter with value, default one will be ignored. NULL value for mail profile name means that sp_send_dbmail procedure will use default mail profile for user executing code.
E.g.
EXECUTE [dbo].[SQL_Job_Monitor] @mail_profile='Name of your mail profile', @mail_recipients='List of recipients'
EXECUTE [dbo].[SQL_Job_Monitor] @mail_profile='Jobs_profil
ASKER
so i should configure my database mail so that NULL value for mail profile will use my default mail profile.
And I will give my recipients.
Is there anything else I should manually alter in the script?
And I will give my recipients.
Is there anything else I should manually alter in the script?
NULL is the default value for sp_send_dbmail procedure. In case you don't specify any profiles procedure will use profile marked as default for login executing procedure.
Don't hesitate to post problems with code, I'll try to fix them as soon as possible.
Don't hesitate to post problems with code, I'll try to fix them as soon as possible.
ASKER
Sir give me 2 days. i need to get approval for enabling database mail.
Sure,
Take your time, I'm just Daniel btw ;)
Take your time, I'm just Daniel btw ;)
ASKER
Sir meanwhile can you please explain me the code you have written.i have less knowledge in xml query.
I have just updated procedure code. The xml part is to create HTML code to form nice table for your email. You can easily extend it to send other useful info.
Updated code:
Sample table:
Updated code:
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL, -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company.com'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:11pt;} ' +
'</style>' +
'</head>' +
'<body>'
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
SET @TableTail = '</table></body></html>';
SET @Table_Content = @TableHead+'<table cellpadding=0 cellspacing=0 border=0>' +
'<tr bgcolor=#FFEFD8><td align=center><b>Job Name</b></td>' +
'<td align=center><b>Is Running</b></td>' +
'<td align=center><b>Current Step</b></td>' +
'<td align=center><b>Current Rettry Attempt</b></td>' +
'<td align=center><b>Job State</b></td></tr>'
SELECT @Body = (SELECT ROW_NUMBER() OVER(ORDER BY x.job_id) % 2 AS [TRRow],
sj.name AS [TD],
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS [TD],
current_step AS [TD],
current_retry_attempt AS [TD],
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS [TD]
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
FOR XML RAW('tr'), ELEMENTS)
SET @Body = Replace(@Body, '_x0020_', space(1))
SET @Body = Replace(@Body, '_x003D_', '=')
SET @Body = Replace(@Body, '<tr><TRRow>1</TRRow>', '<tr bgcolor=#C6CFFF>')
SET @Body = Replace(@Body, '<TRRow>0</TRRow>', '')
SELECT @Body = @TableHead + @Table_Content + @Body + @TableTail
SET @mail_subject = '[!!!WARNING!!!] Job '+QUOTENAME(ISNULL(@JobName,'UNKNOWN'))+' is running longer than 30 minutes'
EXEC msdb.dbo.sp_send_dbmail
@recipients=@mail_recipients,
@subject = @mail_subject,
@body = @Body,
@body_format = 'HTML' ;
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END
END
END
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
Sample table:
ASKER
Hello Sir,
I tried lot to get an approval but my senior management rejected the request to configure Database mail.
Is it possible to re-write the scipt,which will store the information in the table. So that it will be easy for me configure SSRS report and will help in showing it in a graph.
Information details needed are SQL jobname, SQL job running morethan 30 mins, error message in case of failure,Time the sql job stopped,time the sql job started again,Current status
I tried lot to get an approval but my senior management rejected the request to configure Database mail.
Is it possible to re-write the scipt,which will store the information in the table. So that it will be easy for me configure SSRS report and will help in showing it in a graph.
Information details needed are SQL jobname, SQL job running morethan 30 mins, error message in case of failure,Time the sql job stopped,time the sql job started again,Current status
ASKER
I don't want to sens a mail, just it needs to perform the restart of the SQL Job.And i want store those logs into a table. Since I didn't get approval for enabling database mail,I need to look out for other options.
Check whether this suits you:
CREATE TABLE [msdb].[dbo].[jobs_stats] (
entry_id INT IDENTITY(1,1) NOT NULL,
job_id UNIQUEIDENTIFIER NOT NULL,
job_name NVARCHAR(2000) NOT NULL,
job_status CHAR(7) NOT NULL,
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state NVARCHAR(40) NOT NULL,
entry_date DATETIME NOT NULL,
CONSTRAINT [PK_jobs_stats] PRIMARY KEY CLUSTERED
(entry_id ASC)
)
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL, -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company.com'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:11pt;} ' +
'</style>' +
'</head>' +
'<body>'
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
IF EXISTS (SELECT 1 FROM #xp_results_new)
BEGIN
INSERT INTO [msdb].[dbo].[jobs_stats] (job_id, job_name, job_status, current_step, current_retry_attempt, job_state, entry_date)
SELECT x.job_id,
sj.name as job_name,
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS job_status,
current_step ,
current_retry_attempt ,
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS job_state,
GETDATE() AS entry_date
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
END
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END
END
END
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
ASKER
If it's less than 60 mins, will stop and restart?
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
Here it only stops, will it not start the job again???
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
Here it only stops, will it not start the job again???
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
Hi,
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName --HERE JOB STOPS
WAITFOR DELAY '00:00:05' --WAIT 5 SECONDS
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName -- HERE JOB STARTS
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName --HERE JOB STOPS
WAITFOR DELAY '00:00:05' --WAIT 5 SECONDS
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName -- HERE JOB STARTS
ASKER
If it's less than 60 mins, will stop and restart?
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
The above line i understood,
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
Why we are having one more stop at the end of the sp?
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
The above line i understood,
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
Why we are having one more stop at the end of the sp?
It was retained from the original code. I thought you wanted to keep that part as it was originally. If you wish not to have it there, just remove or comment it out:
CREATE TABLE [msdb].[dbo].[jobs_stats] (
entry_id INT IDENTITY(1,1) NOT NULL,
job_id UNIQUEIDENTIFIER NOT NULL,
job_name NVARCHAR(2000) NOT NULL,
job_status CHAR(7) NOT NULL,
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state NVARCHAR(40) NOT NULL,
entry_date DATETIME NOT NULL,
CONSTRAINT [PK_jobs_stats] PRIMARY KEY CLUSTERED
(entry_id ASC)
)
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL, -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company.com'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:11pt;} ' +
'</style>' +
'</head>' +
'<body>'
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
IF EXISTS (SELECT 1 FROM #xp_results_new)
BEGIN
INSERT INTO [msdb].[dbo].[jobs_stats] (job_id, job_name, job_status, current_step, current_retry_attempt, job_state, entry_date)
SELECT x.job_id,
sj.name as job_name,
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS job_status,
current_step ,
current_retry_attempt ,
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS job_state,
GETDATE() AS entry_date
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
END
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
/*IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END*/
END
END
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
ASKER
Do we need these lines?If we don't use email services.
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company .com'
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;paddi ng-right:5 px;padding -top:1px;p adding-bot tom:1px;fo nt-size:11 pt;} ' +
'</style>' +
'</head>' +
'<body>'
And I want to monitor only ALL - DelHistory SQL job.
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;paddi
'</style>' +
'</head>' +
'<body>'
And I want to monitor only ALL - DelHistory SQL job.
No, you don't need them. Furthermore if you run this proc on SQL 2005 and higher you can shorten code a bit more.
/*CREATE TABLE [msdb].[dbo].[jobs_stats] (
entry_id INT IDENTITY(1,1) NOT NULL,
job_id UNIQUEIDENTIFIER NOT NULL,
job_name NVARCHAR(2000) NOT NULL,
job_status CHAR(7) NOT NULL,
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state NVARCHAR(40) NOT NULL,
entry_date DATETIME NOT NULL,
CONSTRAINT [PK_jobs_stats] PRIMARY KEY CLUSTERED
(entry_id ASC)
)*/
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@job_name VARCHAR(255) = 'ALL - DelHistory SQL' -- Default is set to [ALL - DelHistory SQL]
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
SELECT @job_id = job_id FROM msdb..sysjobs WHERE name = @job_name
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
-- Step 3: Get the current job that exceeded the monitoring threshold
SELECT @JobName=j.name, @job_id=a.job_id, @JobStartTime=a.start_execution_date, @JobRunningTime=DATEDIFF(MINUTE,a.start_execution_date,GETDATE())
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name = @job_name
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_id AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
IF EXISTS (SELECT 1 FROM #xp_results_new)
BEGIN
INSERT INTO [msdb].[dbo].[jobs_stats] (job_id, job_name, job_status, current_step, current_retry_attempt, job_state, entry_date)
SELECT x.job_id,
sj.name as job_name,
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS job_status,
current_step ,
current_retry_attempt ,
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS job_state,
GETDATE() AS entry_date
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
END
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
END
END
DROP TABLE #xp_results
DROP TABLE #xp_results_new
ASKER
Thanks Daniel for helping me all the way.
I created a sp, it complied successfully but when i ran the job it failed with the error
Procedure or functionSQL_Job_Monitor has too many arguments specified. [SQLSTATE 42000] (Error 8144). NOTE: The step was retried the requested number of times (3) without succeeding. The step failed.
I'm using SQL server 2008 R2. So i guess there won't any problem.
I created a sp, it complied successfully but when i ran the job it failed with the error
Procedure or functionSQL_Job_Monitor has too many arguments specified. [SQLSTATE 42000] (Error 8144). NOTE: The step was retried the requested number of times (3) without succeeding. The step failed.
I'm using SQL server 2008 R2. So i guess there won't any problem.
How do you execute proc? By using last code you can pass 2 parameters - @threshold_minute and @job_name
ASKER
I used below code and got an error. Can you point me where I'm wrong.
CREATE TABLE [msdb].[dbo].[jobs_stats] (
entry_id INT IDENTITY(1,1) NOT NULL,
job_id UNIQUEIDENTIFIER NOT NULL,
job_name NVARCHAR(2000) NOT NULL,
job_status CHAR(7) NOT NULL,
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state NVARCHAR(40) NOT NULL,
entry_date DATETIME NOT NULL,
CONSTRAINT [PK_jobs_stats] PRIMARY KEY CLUSTERED
(entry_id ASC)
)
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL, -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
@mail_profile VARCHAR(255)=NULL,
@mail_recipients VARCHAR(512)='test@company.com'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
Set @TableTail = '</table></body></html>';
Set @TableHead = '<html><head>' +
'<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:11pt;} ' +
'</style>' +
'</head>' +
'<body>'
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
IF EXISTS (SELECT 1 FROM #xp_results_new)
BEGIN
INSERT INTO [msdb].[dbo].[jobs_stats] (job_id, job_name, job_status, current_step, current_retry_attempt, job_state, entry_date)
SELECT x.job_id,
sj.name as job_name,
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS job_status,
current_step ,
current_retry_attempt ,
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS job_state,
GETDATE() AS entry_date
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
END
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
/*IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END*/
END
END
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
You need to show me command you execute in that Job.
ASKER
parameter to run the job:
Exec msdb.dbo.SQL_Job_Monitor 60, 0,'<ExcludeJob><JobName JOB="PerfData"/></ExcludeJ ob>'
Exec msdb.dbo.SQL_Job_Monitor 60, 0,'<ExcludeJob><JobName JOB="PerfData"/></ExcludeJ
Right, my fault. There was a bug in code (Fetch Next has too few variables :/).
I've modified code. There are few lines at the end which are commented. If you wish to have in your check job history comment for each job which wasn't candidate for check, please uncomment those lines.
I've modified code. There are few lines at the end which are commented. If you wish to have in your check job history comment for each job which wasn't candidate for check, please uncomment those lines.
IF NOT EXISTS (SELECT 1 FROM msdb.sys.tables WHERE name = 'jobs_stats')
BEGIN
CREATE TABLE [msdb].[dbo].[jobs_stats] (
entry_id INT IDENTITY(1,1) NOT NULL,
job_id UNIQUEIDENTIFIER NOT NULL,
job_name NVARCHAR(2000) NOT NULL,
job_status CHAR(7) NOT NULL,
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state NVARCHAR(40) NOT NULL,
entry_date DATETIME NOT NULL,
CONSTRAINT [PK_jobs_stats] PRIMARY KEY CLUSTERED
(entry_id ASC)
)
END
GO
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 60, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime TINYINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
IF EXISTS (SELECT 1 FROM #xp_results_new)
BEGIN
INSERT INTO [msdb].[dbo].[jobs_stats] (job_id, job_name, job_status, current_step, current_retry_attempt, job_state, entry_date)
SELECT x.job_id,
sj.name as job_name,
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS job_status,
current_step ,
current_retry_attempt ,
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS job_state,
GETDATE() AS entry_date
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
END
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
/*IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END*/
END
END
/*
--If you wish to keep info that particular job is not candidate for check please remove comments in this part of code
ELSE
PRINT 'Job '+@JobName+' is not running longer that 30 seconds and wasn''t checked!'
*/
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
ASKER
for testing purpose,I have created the changed the parameter value.
@threshold_minute int = 1 and schedule it to run every 1 minute.
parameter to run the job:
Exec msdb.dbo.SQL_Job_Monitor 1, 0,'<ExcludeJob><JobName JOB="PerfData"/></ExcludeJ ob>
created another job which will execute for 5:00 minutes.But the monitoring job wasn't able to capture the job and didn't restart it.
Wait job executed sucessfully.
And there was no entry logged into jobs_stats table.Is that anything I'm missing.
Alter JOB
Wait job sp's
@threshold_minute int = 1 and schedule it to run every 1 minute.
parameter to run the job:
Exec msdb.dbo.SQL_Job_Monitor 1, 0,'<ExcludeJob><JobName JOB="PerfData"/></ExcludeJ
created another job which will execute for 5:00 minutes.But the monitoring job wasn't able to capture the job and didn't restart it.
Wait job executed sucessfully.
And there was no entry logged into jobs_stats table.Is that anything I'm missing.
Alter JOB
USE [msdb]
GO
/****** Object: StoredProcedure [dbo].[SQL_Job_Monitor] Script Date: 06/23/2012 21:49:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SQL_Job_Monitor] (
@threshold_minute int = 1, -- Default is set to 60 minutes
@StopJob bit = 0, -- Default is not to stop the job
@ExcludeJOb XML =NULL -- '<ExcludeJob><JobName JOB="SQL SERVER JOB"/></ExcludeJob>'
)
AS
SET NOCOUNT ON
DECLARE @is_sysadmin INT
DECLARE @job_owner SYSNAME
DECLARE @job_id UNIQUEIDENTIFIER
DECLARE @JobName VARCHAR(255)
DECLARE @JobStartTime DateTime
DECLARE @JobRunningTime bigINT
DECLARE @Msg VARCHAR(1000)
DECLARE @ExcludeJObTable TABLE (JobName VARCHAR(1000))
DECLARE @Body varchar(max)
DECLARE @TableHead varchar(max)
DECLARE @Table_Content varchar(max)
DECLARE @TableTail varchar(max)
DECLARE @mail_subject VARCHAR(255)
/** Insert the jobs to be excluded from job monitoring */
INSERT @ExcludeJObTable (JobName)
SELECT xmllist.rows.value('@JOB','varchar(1000)')
from @ExcludeJOb.nodes('/ExcludeJob/JobName') xmllist(rows)
-- Step 1: Create intermediate work tables to store the running job data
CREATE TABLE #xp_results (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
CREATE TABLE #xp_results_new (job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL)
-- Step 2: Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
SELECT @job_owner = SUSER_SNAME()
IF ((@@microsoftversion / 0x01000000) >= 8) -- SQL Server 8.0 or greater
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
END
ELSE
BEGIN
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
END
-- Step 3: Get the current job that exceeded the monitoring threshold
DECLARE joblist_cursor CURSOR FOR
SELECT j.name, a.job_id, a.start_execution_date, DATEDIFF(MINUTE,a.start_execution_date,GETDATE()) AS JobRunningTime
FROM #xp_results x
INNER JOIN msdb.dbo.sysjobactivity a
ON x.job_id = a.job_id
INNER join msdb.dbo.sysjobs j
ON a.job_id = j.job_id
WHERE x.running = 1 -- The job is running
AND j.name not IN (SELECT Jobname from @ExcludeJObTable) --Excluding the job Monitoring
AND a.session_id = (select max(session_id) from msdb.dbo.sysjobactivity where job_id = a.job_id)
AND a.stop_execution_date is null -- The job is not complete
-- AND a.start_execution_date <= dateadd(minute, -@threshold_minute, getdate()) -- Measure the thresdhold
OPEN joblist_cursor
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
WHILE @@FETCH_STATUS = 0
BEGIN
-- Check again if the same job at the starting time is still active
IF EXISTS (SELECT TOP 1 * FROM msdb.dbo.sysjobactivity WHERE job_id = @job_ID AND stop_execution_date is NULL AND
@JobRunningTime>30)
BEGIN
IF @JobRunningTime<60
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
WAITFOR DELAY '00:00:05'
PRINT 'Starting job [' + @Jobname + ']'
EXEC msdb..sp_start_job @job_name=@JobName
INSERT INTO #xp_results_new
EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner, @job_id
IF EXISTS (SELECT 1 FROM #xp_results_new)
BEGIN
INSERT INTO [msdb].[dbo].[jobs_stats] (job_id, job_name, job_status, current_step, current_retry_attempt, job_state, entry_date)
SELECT x.job_id,
sj.name as job_name,
CASE running
WHEN 0 THEN 'Stopped'
WHEN 1 THEN 'Running'
END AS job_status,
current_step ,
current_retry_attempt ,
CASE job_state
WHEN 0 THEN 'Not idle or suspended'
WHEN 1 THEN 'Executing'
WHEN 2 THEN 'Waiting For Thread'
WHEN 3 THEN 'Between Retries'
WHEN 4 THEN 'Idle'
WHEN 5 THEN 'Suspended'
WHEN 6 THEN 'Waiting For Step To Finish'
WHEN 7 THEN 'Performing Completion Actions'
END AS job_state,
GETDATE() AS entry_date
FROM #xp_results_new x
JOIN msdb.dbo.sysjobs sj ON x.job_id=sj.job_id
END
TRUNCATE TABLE #xp_results_new;
END
IF @JobRunningTime>=@threshold_minute
BEGIN
SELECT @Msg = 'The SQL Job - [' + @JobName + '] on ' + @@ServerName + ' has exceeded the job running threshold of ' + CONVERT(varchar(3), @threshold_minute) + ' minutes.'
RAISERROR (@Msg, 16, 1) WITH LOG
/*IF @StopJob = 1
BEGIN
PRINT 'Stopping job [' + @Jobname + ']'
EXEC msdb..sp_stop_job @job_name=@JobName
END*/
END
END
--If you wish to keep info that particular job is not candidate for check please remove comments in this part of code
ELSE
PRINT 'Job '+@JobName+' is not running longer that 30 seconds and wasn''t checked!'
FETCH NEXT FROM joblist_cursor
INTO @JobName, @job_id, @JobStartTime, @JobRunningTime
END
CLOSE joblist_cursor
DEALLOCATE joblist_cursor
DROP TABLE #xp_results
DROP TABLE #xp_results_new
GO
Wait job sp's
USE [msdb]
GO
/****** Object: StoredProcedure [dbo].[test] Script Date: 06/23/2012 21:47:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[test]
as
begin
waitfor delay '00:05:00'
end
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Awesome Knowledge.Still there few things to be turned,i will try to post in different question
Can you expand on what you mean when you say - Its Not Working?
That is, it does nothing, it kills said job, but doesn't restart it, ... what?
Regards
David