我有几个应该按顺序运行的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观点中获益。)
答案 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'。