【问题标题】:Using sp_add_jobstep in a job to add a step to that job doesn't actually run the added step?在作业中使用 sp_add_jobstep 向该作业添加步骤实际上并没有运行添加的步骤?
【发布时间】:2019-01-23 14:42:55
【问题描述】:

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

查看作业历史,实际发生的是新作业步骤作为步骤2成功添加,步骤2的名称是添加步骤的名称,但是步骤2生成步骤3应该在此的错误点,即使不应该运行第 3 步。

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

【问题讨论】:

  • 首先,有一个创建一个步骤的步骤就像一个循环引用。这是个坏主意,这听起来像是XY Problem。这里的真正目标是什么?一个问题是 On success 操作 没有指向正确的步骤。另外,不要纠结于步骤名称……这不是引用它们的方式。它们有 step_id 和 step_uid (每个步骤都是唯一的)。此外,我们需要查看您的代码以重现您正在执行的操作...
  • 很难共享代码,因为我在 SQL Server Management Studio 的界面中构建了作业,并且有一些存储过程。真正的目标是一种只在工作日运行工作的偷工减料的方式。如果不是工作日,我希望添加一个工作步骤,作为第 2 步成功退出工作,这样可以避免运行其余的工作。听起来我可能不得不找到另一种方法来做到这一点。
  • 有一个更简单的方法。您如何确定工作日?将其放在步骤 1 中。如果评估结果为假,则退出作业。否则转到第 2 步
  • @scsimon 有。这是我在一些具有非常特殊运行时要求的工作中使用的。如果您只需要 M-F 工作日,您可以将作业计划的频率更改为每周并选择您希望它运行的日期。
  • @scsimon 如何在一个步骤中从存储过程中退出作业?我之前研究过这个问题,除了将工作日检查纳入每个步骤之外找不到解决方案,我试图避免这种情况。

标签: sql-server tsql sql-server-2014 jobs


【解决方案1】:

我认为这项工作的实际运行方式令人困惑。

当您调用一个作业时,它将在您调用它的那一刻完整地运行。如果您在运行过程中对作业进行更改,它们将在您下次运行作业时才会执行(您可以通过添加一个 sp_delete_job 步骤来很容易地验证这一点以尽早删除该作业,您可以看到该作业即使它已被删除,仍将继续执行后续步骤)。

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

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

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

至于名称混淆 - 在流程完成之前不会记录作业历史记录,它使用 INT step_id 而不是步骤的唯一标识符记录信息,这就是为什么您在查看新步骤名称时看到的原因即使执行的底层逻辑来自您最初的第 2 步,历史记录也可能应该被踢到 MS 以切换到使用 UID 以避免这些情况。

【讨论】:

  • 接受这个作为答案,因为这个回复中有一些很好的信息,但我最终使用了 sp_stop_job,它对我的​​目的有用。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    [msdb].[dbo].[sysjobsteps] 表可能是您的朋友。尤其要查看 on_success_action 和 on_fail_action 列。我会确保您添加的步骤之前的步骤具有 3=onSuccessRunNextStep 的 on_success_action。

    这可能有用

    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 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多