从一个主作业顺序调用多个SQL Server Agent作业的好方法?


11

我有几个应顺序运行的SQL Server代理作业。为使应执行的作业保持良好的概览,我创建了一个主作业,该主作业通过调用来调用其他作业EXEC msdb.dbo.sp_start_job N'TEST1'。在sp_start_job瞬间完成(作业步骤1),但我想我的主要工作要等到工作TEST1已经调用下一个工作之前完成。

因此,我编写了这个小脚本,该脚本在作业被调用后立即开始执行(作业步骤2),并迫使主作业等待子作业完成:

WHILE 1 = 1
  BEGIN
    WAITFOR DELAY '00:05:00.000';

    SELECT *
    INTO   #jobs
    FROM   OPENROWSET('SQLNCLI', 'Server=TESTSERVER;Trusted_Connection=yes;',
           'EXEC msdb.dbo.sp_help_job @job_name = N''TEST1'',
           @execution_status = 0, @job_aspect = N''JOB''');

    IF NOT (EXISTS (SELECT top 1 * FROM #jobs))
      BEGIN
        BREAK
      END;

    DROP TABLE #jobs;

  END;

这足够好用。但是我觉得WHILE 1 = 1应该有更聪明和/或更安全(?)的解决方案。

我对以下内容感到好奇,希望您能为我提供一些见解:

  • 这种方法有什么问题?
  • 您能建议一种更好的方法吗?

(我首先在StackOverflow上发布了这个问题,因为我一直专注于代码的改进。仍然有效。但是我的猜测是,这里的人们通常会有更聪明的话来说明为什么我不应该尝试这样做我现在就这样做,或提供其他不错的选择。)

编辑(7月25日)
,根据指出存在问题的答案的数量少,显然我的脚本没有太多错误:-)这种脚本的替代方法似乎是使用一种针对这些问题的工具任务(例如SQL Sentry Event Manager或...)-或自己编写此类工具。我们不会在目前的公司购买这样的工具,所以现在我只坚持使用脚本。


您是否考虑过将这些工作作为主要工作的步骤,而不是独立工作?这将降低复杂性,尤其是如果仅以这种方式依次调用它们的话……
亚伦·伯特兰

这是一个平衡。如果将所有作业作为主要作业的步骤添加,将是“更清洁”的维护,但是这样做会丢失很多概述,并且无法手动运行特定作业。因此,我当然考虑过,但是当前的“解决方案”具有太多优势-只要可行。

Answers:


9

免责声明:我为SQL Sentry工作。

我们的SQL Sentry Event Manager产品具有专门用于此目的的功能:链接作业并将其按各种工作流顺序排列。

几年前,在我加入公司之前,我就开始使用SQL Sentry来做到这一点。我想要的是一种在生产备份完成后立即在我们的测试服务器上开始还原作业的方法。

我最初实现的只是备份作业开始时间和还原开始时间之间的大量缓冲。这并非万无一失。由于备份时间各不相同,因此缓冲区经常使我们浪费时间,即使恢复恢复也没有开始。有时缓冲区还不够。

接下来实现的功能与您拥有的功能类似–我在测试服务器上写了一份作业,该作业在预定备份后不久开始,并不断轮询以查看该作业何时完成。后来将其修改为仅在备份作业中执行了第二步,即更新了测试服务器上的表。没什么大不了,除了还原作业只需要在本地查看表而不是远程监视作业历史记录。回想一下,这可能是该表被调用的触发器,sp_start_job因此该作业不必每隔n分钟运行一次(或根本没有安排好时间)。

最终的解决方案是将作业链接在一起……当服务器A上的备份完成时,事件管理器将在服务器B上启动还原作业。并且如果存在第三项,第四项或基于操作的条件逻辑当工作失败与成功等时,这一切都可以解决。工作流设计人员会提醒您很多SSIS:

在此处输入图片说明

当然,我所描述的基本机制不是火箭手术。如果您坐下来做的话,可以自己编写这种类型的链式包装纸。仅在不需要时为您提供另一种选择。


2

您的方法的主要问题是,您必须不断循环,直到发生某件事(这可能是很长的时间,甚至永远不会发生),并且感觉不太正确。这就是为什么我猜你在问这个问题。

那么,如何使用数据驱动的方法来解决问题?例如,创建一个“审计”表,每个作业在开始和结束时都会写入该表:

职位名称| 开始时间 时间结束
--------- + ------------------- + ------------------
Test1 2012-07-26 07:30 2012-07-26 07:35

创建一个“处理”表,该表列出了所有作业及其执行的顺序:

职位名称| 运行订单
--------- + ---------
测试1 | 1个
测试2 | 2
测试3 | 3

在审计表上创建一个插入触发器,以便在作业完成并插入审计记录时,触发器在处理表中查询下一个作业(按运行顺序),然​​后启动它。

这种方法的好处是:

  1. 开发和维护非常简单。
  2. 它可以通过处理表添加新作业或更改现有作业的顺序,而无需更改代码行。
  3. 审核表可让您了解事件发生的时间。
  4. 它不会浪费CPU周期。仅当发生某些情况时,触发器才会触发。
  5. 认为合适的😉

高温超导


1
非常感谢,喜欢您的回答!我一定会试试看!
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.