Not all errors can be caught by TRY/CATCH
. In this case, sp_start_job
actually calls external procedures, and these are outside the bounds of SQL Server's error handling. Or at least that's the story that they're sticking to:
http://connect.microsoft.com/SQLServer/feedback/details/362112/sp-start-job-error-handling
Also note that this is still a problem in SQL Server 2012 SP1 CU3. Please vote and comment if you want this bug fixed.
A tedious but viable workaround, which requires certain permissions and in this case assumes the job owner is sa
:
DECLARE @x TABLE
(
a VARBINARY(32),b INT,c INT,d INT,e INT,f INT,g INT,h INT,i NVARCHAR(64),
Running BIT, -- the only important column
k INT,l INT,m INT
);
DECLARE @job_id UNIQUEIDENTIFIER;
SELECT @job_id = job_id FROM msdb.dbo.sysjobs WHERE name = N'test2';
INSERT @x EXEC master.dbo.xp_sqlagent_enum_jobs 1, N'sa', @job_id;
IF EXISTS (SELECT 1 FROM @x WHERE Running = 0)
BEGIN
EXEC msdb.dbo.sp_start_job @job_name = N'test2';
END
ELSE
BEGIN
PRINT 'error';
END
Even better might be:
DECLARE @job_id UNIQUEIDENTIFIER, @d DATETIME;
SELECT @job_id = job_id FROM msdb.dbo.sysjobs WHERE name = N'test2';
SELECT @d = stop_execution_date
FROM msdb.dbo.sysjobactivity WHERE job_id = @job_id;
IF @d IS NOT NULL
BEGIN
EXEC msdb.dbo.sp_start_job @job_name = N'test2';
END
ELSE
BEGIN
PRINT 'error';
END
In either case, it is still possible that the job has started between the check for its status and the call to start it, so this doesn't eliminate errors from sp_start_job
altogether, but it makes them far less likely to occur.