在作业中使用 sp_add_jobstep 向该作业添加步骤实际上并不是 运行 添加的步骤吗?

Using sp_add_jobstep in a job to add a step to that job doesn't actually run the added step?

作为测试,我创建了一个包含 2 个步骤的作业。第一步添加一个新的jobstep作为step 2,添加的step等待10秒后退出job报成功。下一步会产生错误,但在添加新步骤后,这永远不会是 运行。

查看作业历史记录,实际发生的是新作业步骤作为步骤2成功添加,步骤2的名称是添加步骤的名称,但是步骤2产生了步骤3应该的错误在这一点上,即使第 3 步不应该是 运行.

本质上,运行就好像第 2 步不存在一样。在作业历史记录中,步骤 2 被称为正确的步骤名称,但 运行 的代码实际上是步骤 3.

我认为人们对这份工作的实际情况感到困惑 运行。

当您调用一个作业时,它将 运行 完整地保持在您调用它时存在的状态。如果您作为 运行 的一部分对作业进行更改,它们将在您下次 运行 作业之前执行(您可以通过添加 sp_delete_job 步骤来轻松验证这一点尽早删除作业,您可以看到作业仍会继续执行后续步骤,即使它已被删除。

因此,当您最初调用作业时,它将完全执行您所拥有的:

  • 第 1 步:创建新的第 2 步
  • 第 2 步:抛出错误

这就是为什么你不能通过添加一个新步骤来绕过它来绕过你原来的第二步。就 SQL 服务器而言,此执行不存在新步骤。

至于名称混淆 - 作业历史直到过程完成才被记录,并且它使用 INT step_id 而不是步骤的唯一标识符来记录信息,这就是为什么你看到新的查看历史记录时的步骤名称,即使执行的基础逻辑来自您的原始步骤 2。可能应该被踢到 MS 以切换到使用 UID 以避免这些情况。

回答我自己的问题,以防其他人遇到与我类似的情况。

其他用户建议抛出一个错误,这肯定会起作用,但是在我的数据库中,所有计划作业的错误都会被记录和审查。我之所以要停工是因为我想避免运行在节假日打工,所以抛错会引起不必要的审核。

对我有用的是创建一个存储过程来检查今天是否是假期。如果不是假期,工作​​照常进行。如果是假期,作业将使用 msdb.dbo.sp_stop_job 停止作业而不会出错。其中一些工作 运行 每月一次,所以我还使用 sp_add_schedule 和 sp_attach_schedule 创建并附加了一个一次性 运行 供第二天使用。

[msdb].[dbo].[sysjobsteps] table 可能是您的朋友。尤其要检查 on_success_action 和 on_fail_action 列。我会确保在您添加的步骤之前的步骤的 on_success_action.

有 3=onSuccessRunNextStep

这可能会有用

DECLARE @MaxJobStep_id INT
DECLARE @Job_id NVARCHAR(500)

SELECT @Job_id= job_id FROM sysjobs
WHERE name IN ('InsertJobNameHere')

SELECT  @MaxJobStep_id = MAX(Step_id)
FROM sysjobsteps
WHERE job_id =  @Job_id

EXEC sp_update_jobstep   
     @job_name = 'InsertJobNameHere' 
     , @step_id = @MaxJobStep_id 
     , @on_success_action = 3   
     , @on_fail_action = 3