Sql-Server

作業類別中的任何作業失敗時發出警報

  • May 7, 2020

是否可以在 SQL Server 2008 中設置警報,以便在特定類別的作業失敗時發送電子郵件?

我想知道,因為我想在 SSRS 訂閱失敗時設置電子郵件 - 所有這些訂閱都是Report Server類別中的作業。

編輯- 事實證明,當 SSRS 訂閱失敗時,作業本身不會失敗,所以我的問題不適用於 SSRS 訂閱監控使用。但是我仍然想知道我們在我們的環境中執行的其他工作

您可以創建一個作業,每分鐘檢查一次 msdb.dbo.sysjobhistory 表(或者您想要的頻率)。您可能希望實現一個隊列表,以便您只為任何單個實例故障發送一次消息。

USE msdb;
GO

CREATE TABLE dbo.ReportServerJob_FailQueue
(
 job_id UNIQUEIDENTIFIER,
 run_date INT,
 run_time INT, -- horrible schema, just matching sysjobhistory
 sql_message_id INT,
 sent BIT NOT NULL DEFAULT 0,
 PRIMARY KEY (job_id, run_date, run_time)
);

因此,您可以在作業中安排的程式碼變為:

INSERT dbo.ReportServerJob_FailQueue
 (job_id, run_date, run_time, sql_message_id)
SELECT job_id, run_date, run_time, sql_message_id
FROM msdb.dbo.sysjobhistory AS h
WHERE step_id = 0 
AND run_status = 0
AND EXISTS 
(
 SELECT 1 FROM msdb.dbo.sysjobs AS j
   INNER JOIN msdb.dbo.syscategories AS c
   ON j.category_id = c.category_id
   WHERE j.job_id = h.job_id
  AND c.name = 'Report Server'
)
AND NOT EXISTS 
(
 SELECT 1 FROM dbo.ReportServerJob_FailQueue
   WHERE job_id = h.job_id
   AND run_date = h.run_date
   AND run_time = h.run_time
);

現在我假設您想為每次失敗發送一封單獨的電子郵件,因此這也可能是工作的一部分(或不同工作的一部分,儘管這不一定是明智的):

DECLARE 
 @subject NVARCHAR(4000),
 @body NVARCHAR(4000),
 @name SYSNAME,
 @id UNIQUEIDENTIFIER,
 @date INT,
 @time INT,
 @msg INT;

DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT q.job_id, q.run_date, q.run_time, q.sql_message_id, j.name
 FROM dbo.ReportServerJob_FailQueue AS q
 INNER JOIN msdb.dbo.sysjobs AS j
 ON q.job_id = j.job_id
 WHERE q.sent = 0;

OPEN c;

FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;

WHILE @@FETCH_STATUS = 0
BEGIN

 SET @subject = 'Report Server job ' + @name + ' failed.';
 SET @body = 'Error number: ' + RTRIM(@msg);

 BEGIN TRY
   EXEC msdb.dbo.sp_send_dbmail 
     @profile_name = 'default',     -- you may need to change this
     @recipients   = 'foo@bar.com', -- you will need to change this
     @subject      = @subject,
     @body         = @body;

   UPDATE dbo.ReportServerJob_FailQueue
     SET sent = 1 
     WHERE job_id = @id
     AND run_date = @date
     AND run_time = @time;
 END TRY
 BEGIN CATCH
   PRINT 'Will have to try that one again later.';
 END

 FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;
END

CLOSE c; DEALLOCATE c;

還有一些其他的選擇:

  • 拉入 sysjobhistory.message
  • 查看失敗的各個步驟
  • 即使有多次失敗,也只能在 n 分鐘/小時內為任何作業發送一次消息
  • 發送一封包含所有失敗作業列表的電子郵件,而不是每次失敗的電子郵件
  • 您可能希望在消息中包含 run_date 和 run_time,因為電子郵件的發送或接收速度可能不夠快,無法準確衡量作業實際失敗的時間(我沒有在此處包含它,因為它們可怕的數據類型選擇將這些東西格式化為皇家 PITA)
  • 您可能希望在一段時間後清理舊行,因此可能還需要一個 purge 命令

如果尚未設置數據庫郵件,請參閱本教程

您還可以使用 3rd 方工具(例如SQL Sentry),這將使這一切變得更簡單。完全披露:我為 SQL Sentry 工作。

引用自:https://dba.stackexchange.com/questions/18153