获取SQL Server作业状态

时间:2013-01-18 17:30:12

标签: sql sql-server sql-server-2008

我正在尝试获取MS SQL Server中的作业状态,目的是在我们的远程监控软件中创建一个警报,如果任何已启用的作业有错误。

目前我正在使用sys.xp_sqlagent_enum_jobs存储过程但是这似乎同时显示了启用和禁用的作业,所以我尝试使用msdb.dbo.sp_help_job,这正是我需要但不使用OPENQUERY参数(在服务器上被禁用)由于嵌套错误,我无法查询或捕获结果,我对sp_get_composite_job_info也一样。

所以我开始没有想法,有没有人知道如何捕获这些信息以供查询或稍后存储在一个能查询中。

我将包含我当前的代码,以防它对任何人都有用,它可以很好地返回失败的作业数量,但是如果你有一个失败的作业被禁用,这也会显示出来。

objRecordSet.Open _
"SET  NOCOUNT ON " & _
"DECLARE @MaxLength INT " & _
"SET @MaxLength   = 50 " & _
"DECLARE @xp_results TABLE ( job_id uniqueidentifier NOT NULL, " & _
    "last_run_date nvarchar (20) NOT NULL, " & _
    "last_run_time nvarchar (20) NOT NULL, " & _
    "next_run_date nvarchar (20) NOT NULL, " & _
    "next_run_time nvarchar (20) NOT NULL, " & _
    "next_run_schedule_id INT NOT NULL, " & _
    "requested_to_run INT NOT NULL, " & _
    "request_source INT NOT NULL, " & _
    "request_source_id sysname " & _
    "COLLATE database_default NULL, " & _
    "running INT NOT NULL, " & _
    "current_step INT NOT NULL, " & _
    "current_retry_attempt INT NOT NULL, " & _
    "job_state INT NOT NULL " & _
")" & _
"DECLARE @job_owner sysname " & _
"DECLARE @is_sysadmin INT " & _
"SET @is_sysadmin = isnull (is_srvrolemember ('sysadmin'), 0) " & _
"SET @job_owner = suser_sname () " & _
"INSERT INTO @xp_results EXECUTE sys.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner " & _
"UPDATE @xp_results SET last_run_time = right ('000000' + last_run_time, 6), next_run_time = right ('000000' + next_run_time, 6) " & _
"SELECT count(*) as cnt FROM @xp_results x LEFT JOIN msdb.dbo.sysjobs j ON x.job_id = j.job_id LEFT OUTER JOIN msdb.dbo.syscategories c " & _
"ON j.category_id = c.category_id LEFT OUTER JOIN msdb.dbo.sysjobhistory h ON x.job_id = h.job_id " & _
"AND x.last_run_date = h.run_date AND x.last_run_time = h.run_time AND h.step_id = 0 where h.run_status = 0 ", _
objConnection, adOpenStatic, adLockOptimistic

message = message & "JOBCHECK#" & objRecordSet("cnt") & vbNewLine 

2 个答案:

答案 0 :(得分:3)

没那么难。请记住,SQL Server始终保持元数据信息,以便主动对服务器执行哪些详细信息。我会这样做是为了找到失败,因为你可以创建一个proc或函数,按日期范围调用它。我暂时给出了一个查询的例子:

use msdb;

declare
    @Start int =  cast( convert(varchar,  
            dateadd(ww, datediff(ww, 0, getdate())-1,0)  -- last week starting
            , 112) as int)
,   @End int = cast( convert(varchar,
            getdate()  -- current datetime
            , 112) as int)
;

Select 
    j.name
,   j.description
,   cast( cast(jh.run_date as varchar) + ' ' +  left(jh.run_time, 2) + ':' + substring( cast(jh.run_time as varchar), 3, 2) as datetime) as TimeRan
,   jh.message
,   jh.step_id
,   jh.step_name
from sysjobs j (nolock) 
    join sysjobhistory jh (nolock) on j.job_id = jh.job_id
        and jh.run_date between @Start and @End
        and jh.run_status = 0  -- 0 is failure

答案 1 :(得分:0)

非常感谢使用djangojazz的帮助,我能够做我想做的事:

use msdb;
Select count(*) as cnt
from sysjobs j (nolock) 
    join sysjobhistory jh (nolock) on j.job_id = jh.job_id
    and instance_id = (
        select MAX(instance_id) 
        from sysjobhistory (nolock)
        where job_id = j.job_id
        )
    and j.enabled = 1
    and jh.run_status = 0