Alert when SQL Server jobs fail

I would always recommend an enterprise monitoring solution for your important SQL Servers. There may be some that are less important though. You can always configure alerts at an individual job level, you can create triggers or extended events to notify you, or even use base alerts in SQL Server. If you need a quick and dirty solution to throw into place temporarily though, I like this option.

Here we have a T-SQL statement that we can either create as a stored procedure or just run as T-SQL in a job step. It looks back over the last 10 minutes and looks for job failures. I would recommend scheduling this T-SQL to run every 5 minutes, you will get duplicate entries for a short period of time, but ideally, you shouldn’t get any failures anyway right? Plus once you’re notified, you can turn this off while you work on it or you can specify in the where clause to remove this job until fixed.

Here is the code for the alert. YOU WILL NEED TO ADD THE EMAIL ADDRESS TO SEND TO, otherwise it is ready for you to use assuming your mail server on SQL Server is already set up.


/********************
 SQL variable declare
********************/

DECLARE @PreviousDate DATETIME;

DECLARE @Year VARCHAR(4);

DECLARE @Month VARCHAR(2);

DECLARE @MonthPre VARCHAR(2);

DECLARE @Day VARCHAR(2);

DECLARE @DayPre VARCHAR(2);

DECLARE @FinalDate INT;

/********************************
 Table and email variable declare
********************************/

DECLARE @Body VARCHAR(MAX);

DECLARE @TableHead VARCHAR(MAX);

DECLARE @TableTail VARCHAR(MAX);

DECLARE @ProfileName SYSNAME;

DECLARE @tRecipients VARCHAR(400);

DECLARE @Server SYSNAME;

DECLARE @tSubject VARCHAR(255);

DECLARE @tBody VARCHAR(MAX);

DECLARE @tImportance VARCHAR(6);

DECLARE @Subquery TABLE
([name]         VARCHAR(MAX), 
 [step_name]    VARCHAR(MAX), 
 [step_id]      VARCHAR(MAX), 
 [step_name2]   VARCHAR(MAX), 
 [run_date]     VARCHAR(MAX), 
 [run_time]     VARCHAR(MAX), 
 [sql_severity] VARCHAR(MAX), 
 [message]      VARCHAR(MAX), 
 [server]       VARCHAR(MAX), 
 [instance_id]  VARCHAR(MAX), 
 [command]      VARCHAR(MAX)
);

/*********************
 Initialize Variables 
*********************/

SET @PreviousDate = DATEADD([dd], -90, GETDATE());

/************
 Last 7 days 
************/

SET @Year = DATEPART([yyyy], @PreviousDate);

SELECT 
       @MonthPre = CONVERT(VARCHAR(2), DATEPART([mm], @PreviousDate));

SELECT 
       @Month = RIGHT(CONVERT(VARCHAR, (@MonthPre + 1000000000)), 2);

SELECT 
       @DayPre = CONVERT(VARCHAR(2), DATEPART([dd], @PreviousDate));

SELECT 
       @Day = RIGHT(CONVERT(VARCHAR, (@DayPre + 1000000000)), 2);

SET @FinalDate = CAST(@Year + @Month + @Day AS INT);

INSERT INTO @Subquery
(
       [name], 
       [step_name], 
       [step_id], 
       [step_name2], 
       [run_date], 
       [run_time], 
       [sql_severity], 
       [message], 
       [server], 
       [instance_id], 
       [command]
)
SELECT 
       [j].[name] AS         [name], 
       [s].[step_name] AS    [step_name], 
       [h].[step_id] AS      [step_id], 
       [h].[step_name] AS    [step_name], 
       [h].[run_date] AS     [run_date], 
       [h].[run_time] AS     [run_time], 
       [h].[sql_severity] AS [sql_severity], 
       [h].[message] AS      [message], 
       [h].[server] AS       [server], 
       [h].[instance_id], 
       [s].[command]
FROM [msdb].[dbo].[sysjobhistory] AS [h]
     INNER JOIN [msdb].[dbo].[sysjobs] AS [j] ON [h].[job_id] = [j].[job_id]
     INNER JOIN [msdb].[dbo].[sysjobsteps] AS [s] ON [j].[job_id] = [s].[job_id]
                                                     AND [h].[step_id] = [s].[step_id]
WHERE [h].[run_status] = 0
      AND [msdb].[dbo].[agent_datetime] ([run_date], [run_time]) >= DATEADD([mi], -10, Current_TimeStamp);

IF
(
(
    SELECT 
           COUNT(*)
    FROM @SubQuery
)
) > 0
    BEGIN

/*************
-- SEND EMAIL 
*************/

        SET @TableTail = '';
        SET @TableHead = ''+''+''+''+''+''+''+''+''+''+''+''+''+'';

        SELECT 
               @Body =
        (
            SELECT 
                   ROW_NUMBER() OVER(ORDER BY [Command]) % 2 AS [TRRow], 
                   [name] AS                                    [TD], 
                   [step_name] AS                               [TD], 
                   [step_id] AS                                 [TD], 
                   [step_name2] AS                              [TD], 
                   [run_date] AS                                [TD], 
                   [run_time] AS                                [TD], 
                   [sql_severity] AS                            [TD], 
                   [message] AS                                 [TD], 
                   [server] AS                                  [TD]
            FROM @subquery
            ORDER BY 
                     [instance_id] DESC FOR
            XML RAW('tr'), ELEMENTS
        );

/****************************************
#4286f4 C6CFFF #f4aa42 #FFFF99
 Replace the entity codes and row numbers
****************************************/

        SET @Body = REPLACE(@Body, '_x0020_', SPACE(1));
        SET @Body = REPLACE(@Body, '_x003D_', '=');
        SET @Body = REPLACE(@Body, '1', '');
        SET @Body = REPLACE(@Body, '0', '');

        SET @Server =
        (
            SELECT 
                   @@SERVERNAME
        );

        SET @tSubject = 'From '+@Server+'. Failed Job History for the last 10 minutes';

        SELECT 
               @Body = @TableHead + @Body + @TableTail, 
               @profilename = [name], 
               @tRecipients = 'EMAIL ADDRESS GOES HERE@GMAIL.COM', 
               @tBody = @Body, 
               @tImportance = 'NORMAL'
        FROM [msdb].[dbo].[sysmail_profile];

        EXECUTE [msdb].[dbo].[sp_send_dbmail] 
                @profile_name = @ProfileName
              , @Recipients = @tRecipients
              , @Subject = @tSubject
              , @Body = @tBody
              , @Body_Format = 'HTML'
              , @Importance = @tImportance;
    END;
    ELSE
    BEGIN
        PRINT 'all good';
    END;

Leave a Reply

Your email address will not be published. Required fields are marked *

NameStep_NameStep_IDStep_NameRun_DateRun_TimeSQL_SeverityMessageServer