Sql-Server-2016

為 is_event_logged = 0 的事件引發錯誤嚴重性 16 警報

  • January 11, 2022

我有一個錯誤級別 16 警報設置如下:

USE [msdb]
GO

EXEC msdb.dbo.sp_add_alert @name=N'Error - Severity 16', 
       @message_id=0, 
       @severity=16, 
       @enabled=1, 
       @delay_between_responses=0, 
       @include_event_description_in=1, 
       @category_name=N'[Uncategorized]', 
       @job_id=N'00000000-0000-0000-0000-000000000000'

我很好奇為什麼

SELECT 1/0;

消息 8134,級別 16,狀態 1,第 17 行遇到除以零錯誤。

沒有引發錯誤,但

BACKUP DATABASE MyDatabase TO DISK = 'C:\FolderThatDoesntexist'

消息 3201,級別 16,狀態 1,第 8 行無法打開備份設備“C:\FolderThatDoesntexist”。作業系統錯誤 5(拒絕訪問。)。

消息 3013,級別 16,狀態 1,第 8 行備份數據庫異常終止。

曾是

這篇文章它引用的部落格文章表明 SQL Server 只會為記錄的錯誤引發事件,這可以在sys.messages

所以我查詢sys.messages了這些錯誤程式碼:

SELECT  severity,
       message_id,
       is_event_logged
FROM    sys.messages
WHERE   language_id = 1033 AND
       message_id IN (8134,3201,3013)

但發現三個都設置為0:

在此處輸入圖像描述

為什麼 3201 和 3013 會觸發我的警報而 8134 不會?

只有發送到 windows 應用程序事件日誌的事件才能用於警報。

這可以在指定RAISERROR時完成,WITH LOG請參閱文件

以下程式碼將產生 2 個錯誤,第二個將發送到事件日誌,第一個不會。第二個會觸發你的警報,第一個不會。

RAISERROR('Test for dba.stackexchange 1', 16, 1);
RAISERROR('Test for dba.stackexchange 2', 16, 1) WITH LOG;

事件簿

作業系統錯誤(如訪問被拒絕、磁碟空間不足……)被記錄到 Windows 的應用程序事件日誌中。

除以零不會記錄到 Windows 的應用程序事件日誌中。

這是觸發備份錯誤警報的消息。

SELECT *
FROM sys.messages
WHERE 1=1
AND is_event_logged = 1
AND Severity = 16
AND message_id IN (3041,18204)
AND language_id = 1033

哪些是在 SSMS 和您的查詢中顯示的不同消息。您可以通過提供過濾器在警報上對此進行測試。message_id 在事件日誌中可見: 在此處輸入圖像描述

如何觸發警報

您可以像這樣包裝您的程式碼並重新引發異常WITH LOG,然後您的警報應該會起作用。

DECLARE 
   @ErrorMessage  NVARCHAR(4000), 
   @ErrorSeverity INT, 
   @ErrorState    INT;

BEGIN TRY
   SELECT 1/0;
END TRY
BEGIN CATCH
   SELECT 
       @ErrorMessage = ERROR_MESSAGE(), 
       @ErrorSeverity = ERROR_SEVERITY(), 
       @ErrorState = ERROR_STATE();

   RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState) WITH LOG;
END CATCH;

用日誌重新拋出

另請閱讀 SQL 伺服器警報的備註

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