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