SQL 尽管有错误处理,但代理作业在某个步骤失败
SQL agent job failing at a step despite error handling
我的 SQL 服务器实例有一个名为 Grand Master
的代理作业,该作业 运行 每分钟执行一次计划,每天 7 天,每天 24 小时。
我创建了另一个需要不时手动 运行 的作业。它需要做的第一件事就是在 运行ning 处于活动状态时禁用并停止 Grand Master
作业。
第 1 步是禁用 GM,效果很好:
exec msdb..sp_update_job @job_name = "Grand Master", @Enabled = 0
但是第 2 步失败了。它的工作是阻止 GM 从 运行ning IF 它是 运行ning。如果 GM 当前未 运行ning:
,则不应执行任何操作
if exists (select 1
from msdb.dbo.sysjobs_view j
join msdb.dbo.sysjobactivity a on j.job_id = a.job_id
where a.run_requested_date is not null
and a.stop_execution_date is null
and j.name = 'Grand Master')
begin
exec msdb.dbo.sp_stop_job 'Grand Master'
end
每次我 运行 这个作业,无论 GM 的状态如何,它都会在第 2 步失败并出现以下错误:
Executed as user: NT AUTHORITY\SYSTEM. SQLServerAgent Error: Request to stop job Grand Master (from User NT AUTHORITY\SYSTEM) refused because the job is not currently running. [SQLSTATE 42000] (Error 22022). The step failed.
有没有人有什么想法?
如果是 运行,请先停止它,然后禁用该作业。 SQL 服务器可能会误解停止禁用作业的想法...
如果您的工作环境混乱,上述查询可能会显示与 Job Activity Monitor 不同的结果(恕我直言,GUI 信息更可靠)。您可以使用下一个过程来检查作业是否处于“正在执行”状态。该程序由您自行负责。
/*
程序结果:0=未空闲或挂起,1=正在执行,2=WaitingForThread,3=BetweenRetries,4=Idle,5=Suspended,[6=WaitingForStepToFinish],7=PerformingCompletionActions
*/
CREATE PROCEDURE [dbo].[sp_get_job_state] (
@job_name VARCHAR(100)
, @job_state SMALLINT OUTPUT
)
AS
BEGIN
DECLARE @job_id UNIQUEIDENTIFIER
, @can_see_all_running_jobs INT = 1
, @job_owner SYSNAME = SUSER_SNAME()
, @res SMALLINT;
DECLARE @xp_results TABLE (
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 COLLATE database_default NULL
, running INT NOT NULL
, -- BOOL
current_step INT NOT NULL
, current_retry_attempt INT NOT NULL
, job_state INT NOT NULL
);
SELECT @job_id = job_id
FROM msdb..sysjobs
WHERE name = @job_name;
INSERT INTO @xp_results (
job_id
, last_run_date
, last_run_time
, next_run_date
, next_run_time
, next_run_schedule_id
, requested_to_run
, request_source
, request_source_id
, running
, current_step
, current_retry_attempt
, job_state
)
EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs = @can_see_all_running_jobs
, @job_owner = @job_owner
, @job_id = @job_id;
SELECT @job_state = job_state
FROM @xp_results
END
我的 SQL 服务器实例有一个名为 Grand Master
的代理作业,该作业 运行 每分钟执行一次计划,每天 7 天,每天 24 小时。
我创建了另一个需要不时手动 运行 的作业。它需要做的第一件事就是在 运行ning 处于活动状态时禁用并停止 Grand Master
作业。
第 1 步是禁用 GM,效果很好:
exec msdb..sp_update_job @job_name = "Grand Master", @Enabled = 0
但是第 2 步失败了。它的工作是阻止 GM 从 运行ning IF 它是 运行ning。如果 GM 当前未 运行ning:
,则不应执行任何操作if exists (select 1
from msdb.dbo.sysjobs_view j
join msdb.dbo.sysjobactivity a on j.job_id = a.job_id
where a.run_requested_date is not null
and a.stop_execution_date is null
and j.name = 'Grand Master')
begin
exec msdb.dbo.sp_stop_job 'Grand Master'
end
每次我 运行 这个作业,无论 GM 的状态如何,它都会在第 2 步失败并出现以下错误:
Executed as user: NT AUTHORITY\SYSTEM. SQLServerAgent Error: Request to stop job Grand Master (from User NT AUTHORITY\SYSTEM) refused because the job is not currently running. [SQLSTATE 42000] (Error 22022). The step failed.
有没有人有什么想法?
如果是 运行,请先停止它,然后禁用该作业。 SQL 服务器可能会误解停止禁用作业的想法...
如果您的工作环境混乱,上述查询可能会显示与 Job Activity Monitor 不同的结果(恕我直言,GUI 信息更可靠)。您可以使用下一个过程来检查作业是否处于“正在执行”状态。该程序由您自行负责。
/* 程序结果:0=未空闲或挂起,1=正在执行,2=WaitingForThread,3=BetweenRetries,4=Idle,5=Suspended,[6=WaitingForStepToFinish],7=PerformingCompletionActions */
CREATE PROCEDURE [dbo].[sp_get_job_state] (
@job_name VARCHAR(100)
, @job_state SMALLINT OUTPUT
)
AS
BEGIN
DECLARE @job_id UNIQUEIDENTIFIER
, @can_see_all_running_jobs INT = 1
, @job_owner SYSNAME = SUSER_SNAME()
, @res SMALLINT;
DECLARE @xp_results TABLE (
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 COLLATE database_default NULL
, running INT NOT NULL
, -- BOOL
current_step INT NOT NULL
, current_retry_attempt INT NOT NULL
, job_state INT NOT NULL
);
SELECT @job_id = job_id
FROM msdb..sysjobs
WHERE name = @job_name;
INSERT INTO @xp_results (
job_id
, last_run_date
, last_run_time
, next_run_date
, next_run_time
, next_run_schedule_id
, requested_to_run
, request_source
, request_source_id
, running
, current_step
, current_retry_attempt
, job_state
)
EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs = @can_see_all_running_jobs
, @job_owner = @job_owner
, @job_id = @job_id;
SELECT @job_state = job_state
FROM @xp_results
END