2013-01-18 82 views
1

我試圖獲取MS SQL Server中的作業狀態,目的是在遠程監視軟件中創建一個警報,如果任何已啓用的作業發生錯誤。獲取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 
+0

是否有必要在這樣做TSQL?如果您可以使用PowerShell或C#等.NET語言,請使用[使用SMO](http://stackoverflow.com/questions/8170438/checking-a-sql-job-status-in-c-sharp-using-sp-幫助工作)會簡單得多。在TSQL中獲得工作細節非常尷尬。 – Pondlife

回答

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 
+0

非常感謝,我能夠修改你的代碼來做我想做的事 – trevrobwhite

+0

沒問題,開心編碼。 – djangojazz

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