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

时间:2012-07-13 14:02:27

标签: sql-server tsql sql-server-2008-r2 sql-server-agent

我有几个应该按顺序运行的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?)解决方案应该是可能的。

我对以下事情感到好奇,希望你能给我一些见解:

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

(我也在dba.stackexchange.com发布了这个问题,以便从更少编程的dba'ing观点中获益。)

2 个答案:

答案 0 :(得分:3)

如果您选择轮询一个表,那么您需要查看msdb.dbo.sysjobhistory并等到run_status不是4.但仍然会icky。

对于作业的最后一步,失败或成功,可能会有一种不同的方法,即在“主”作业服务器上输入该过程已完成的条目,然后您只需查看本地。通过在集中式作业服务器上整合启动和停止,可能还可以更轻松地追踪“发生了什么”。

第三种更强大的方法是使用Service Broker之类的方法来处理进程之间的通信和信令。这需要更多的设置,但它是进程之间进行通信的最多机制。

答案 1 :(得分:0)

方法没问题。我有点像你的要求,我使用msdb的sysjobhistory表来查看运行状态,原因还有其他原因。

回到你的问题,请使用相同的方法引用msdb.dbo.sp_start_job存储过程,并且一个默认的Microsoft BizTalk作业'MessageBox_Message_ManageRefCountLog_BizTalkMsgBoxDb'使用它来调用另一个依赖的默认biztalk作业'MessageBox_Message_Cleanup_BizTalkMsgBoxDb'。即使BizTalk消息框中有一个存储过程也可以检查作业的状态。请参阅BizTalk消息框中的'int_IsAgentJobRunning'。