我有一个SQL Server作业,它使用sp_start_job调用其他10个作业。这项工作有10个步骤,每个步骤再次调用子作业。
当我执行主要工作时,我可以看到它从步骤1开始,并在几秒钟内显示“成功完成”。
但是这些作业需要很长时间才能运行,当我验证日志信息时,它会显示所有10个步骤同时在后面运行,直到几小时后完成。
我的要求是它应该先完成第1步,然后才能开始第2步。
答案 0 :(得分:1)
Microsoft Code论坛可以检查存储过程是否正在运行。您可以使用它等到作业完成:
while 1=1
begin
WAITFOR DELAY '000:00:10'
if not exists (
SELECT *
FROM master..sysprocesses p
JOIN msdb..sysjobs j ON
substring(left(j.job_id,8),7,2) +
substring(left(j.job_id,8),5,2) +
substring(left(j.job_id,8),3,2) +
substring(left(j.job_id,8),1,2) =
substring(p.program_name,32,8)
WHERE j.name = 'YourJobName'
AND program_name like 'SQLAgent - TSQL JobStep (Job %'
)
break
end
这样代码的工作方式是等待10秒,然后检查作业YourJobName是否正在运行。它会重复,直到工作不再运行。你可以把它放在sp_start_job调用之间。
话虽如此,必须有一种更简单的方法。你不能存储存储过程中10个作业中的每个作业的代码吗? “主”工作可以调用10个存储过程,而不是启动10个工作。
答案 1 :(得分:0)
我的第一个答案是您可以使用上面的循环,但检查msdb中的作业历史记录表以等待前一个作业完成:
select sj.name as job_name
from msdb.dbo.sysjobhistory sjh
inner join msdb.dbo.sysjobs_view sj on sj.job_id = sjh.job_id
where sjh.step_id = 0 --Job outcome
and sjh.run_status = 4 --In progress
谢谢Andomar提出质疑。事实证明,只有在第一步完成后才会更新sysjobhistory。只有白痴会想象,如果run_status的一个值是'进行中',那么当步骤开始时必须更新表!我四处寻找,这似乎是一个棘手的问题。某处SQL知道发生了什么,但它没有很好地公开信息。
您似乎必须在数英里之间选择复杂的代码或使用未记录的存储过程。您可以轻松找到代码答案的里程数 - 有几个 - 通过谷歌搜索sysjobhistory。我个人更喜欢xp方法:
create table #xp_results(
job_id uniqueidentifier not null,
last_run_date int not null,
last_run_time int not null,
next_run_date int not null,
next_run_time int not null,
next_run_schedule_id int not null,
requested_to_run int not null, -- bool
request_source int not null,
request_source_id sysname collate database_default null,
running int not null, -- bool
current_step int not null,
current_retry_attempt int not null,
job_state int not null )
insert #xp_results exec master.dbo.xp_sqlagent_enum_jobs @is_sysadmin = 1, @job_owner = ''
select sj.name
from #xp_results xpr
inner join msdb.dbo.sysjobs_view sj on sj.job_id = xpr.job_id
where running = 1
drop table #xp_results
我已经对此进行了测试,它似乎确实有效。使用这个xp可能有风险,但这就是Job Activity Monitor使用的 - 我用Profiler运行它 - 所以如果它改变了,它们可能会提供一些其他方法来查找这些信息。只要你将这段代码包装在一个函数或proc和文档中你依赖它,对我来说似乎是最少的祸害。