我目前正在使用这样的代码来检测一个SQL服务器作业是否正在运行。(这是Server 2005,所有SP的)
return (select isnull(  
(select top 1 CASE 
    WHEN current_execution_status = 4 THEN 0
    ELSE 1
    END
from openquery(devtestvm, 'EXEC msdb.dbo.sp_help_job')
where current_execution_status = 4 and
    name = 'WQCheckQueueJob' + cast(@Index as varchar(10))
), 1)
)这里没有问题,一般来说,它工作得很好。
但是...(总是一个但)
有时,我会调用它,得到一个“作业不运行”的结果,在这个时候,我将尝试开始作业,通过
exec msdb.dbo.sp_start_job @JobName而SQL将返回"SQLAgent拒绝启动作业,因为它已经有一个挂起的请求“。
好的。也不成问题。可以想象,在这段代码启动之前,有一个很小的窗口可以启动目标作业,但是在检查它是否已经启动之后。但是,我只需要尝试捕获就可以忽略这个错误,对吗?
begin try
if dbo.WQIsQueueJobActive(@index) = 0 begin
    exec msdb.dbo.sp_start_job @JobName
    break
end         
end try begin catch
    -- nothing here
end catch但问题是。
10次中有9次,效果很好。SQL代理会引发错误,它会被捕获,并且处理将继续进行,因为作业已经在运行,不会造成任何伤害。
但偶尔,我会在“职务历史记录”视图中收到一条消息(请记住上面的代码以检测某个特定的作业是否正在运行,如果没有从另一个作业中实际运行,则启动它)说,作业失败是因为"SQLAgent拒绝启动作业,因为它已经有一个挂起的请求“。
当然,这正是试图捕获应该处理的错误!
当这种情况发生时,执行的作业就会死掉,但据我所知,并不是马上就结束了,非常接近。我到处都放了日志,没有一致性。一旦失败,它就会在a,下一次在b。在某些情况下,A和B只剩下a。
select @var = 'message'在他们中间。很奇怪。基本上,该作业似乎被随意转储,而在作业中剩下的任何执行都是+not+执行的。
但是,如果我删除了"exec StartJob“(或者只调用了一次,当我知道目标作业不能运行时),那么所有操作都会很完美,作业中的所有处理都会完成。
所有这一切背后的目的都是因为触发而启动一个作业(除其他外),如果作业已经启动,就没有必要“再次启动”。
有人在SQL Agent的作业处理中遇到过这样的行为吗?
编辑:当前控制流如下所示:
表(update或insert)...
发布于 2011-08-03 17:35:25
首先,你有机会看一下服务经纪人吗?从你的描述看来,这是你真正想要的。
区别将不是启动作业,而是将数据放到SB队列中,SB将异步和完全地调用您的处理过程,处理已经运行的作业等等。它将自动生成/终止额外的线程,并要求指令,处理顺序等等。
这里有一个很好的(和模糊相关的)教程。http://www.sqlteam.com/article/centralized-asynchronous-auditing-with-service-broker
让我们假设,无论出于什么原因,你都不能使用某人(但说真的,做吧!)
如何使用作业spid的context_info。
您的作业调用一个包装程序,该包装程序对包装程序内的每个步骤individually.
声明@context_info
设置CONTEXT_INFO 0x0
如果不存在(选择*从master..sysprocesses WITH (NOLOCK)其中context_info=CAST('MyJob1‘作为VARBINARY))执行StartJob
当包装器终止或连接关闭时,您的context_info就会消失。
您还可以使用全局临时表(即##JobStatus),当引用它的所有尖峰断开或显式删除时,它们将消失。
只是一些想法。
发布于 2014-09-27 14:52:31
我有一个查询,它给我运行的作业,也许它可以帮助你。它一直为我工作,但如果你发现它的任何错误,让我知道,我会尽力纠正。干杯。
-- get the running jobs
--marcelo miorelli
-- 10-dec-2013
SELECT sj.name
      ,DATEDIFF(SECOND,aj.start_execution_date,GetDate()) AS Seconds
 FROM msdb..sysjobactivity aj
 JOIN msdb..sysjobs sj on sj.job_id = aj.job_id
WHERE aj.stop_execution_date IS NULL -- job hasn't stopped running
 AND aj.start_execution_date IS NOT NULL -- job is currently running
--AND sj.name = 'JobName'
and not exists( -- make sure this is the most recent run
    select 1
    from msdb..sysjobactivity new
    where new.job_id = aj.job_id
      and new.start_execution_date > aj.start_execution_date )发布于 2013-07-10 11:16:17
要处理一个已经在运行的作业: 1.打开任务管理器2。检查带有ImageName "DTExec.exe“的进程是否正在运行3。如果进程正在运行,如果是有问题的作业,则执行"End Process”。
https://stackoverflow.com/questions/5861255
复制相似问题