Уведомить оператора, если ЛЮБОЙ шаг в работе не удался - PullRequest
13 голосов
/ 04 октября 2010

Могу ли я (как мне) настроить Sql Server 2008 для уведомления оператора в случае сбоя какого-либо шага в задании?

У меня есть задание Sql Server с несколькими шагами для обновления данных из нескольких разных источников, затемодним последним шагом, который выполняет несколько расчетов на данных.Все шаги «обновления данных» установлены на «Перейти к следующему шагу при ошибке».Вообще говоря, если одно из обновлений данных завершается неудачно, я все же хочу, чтобы последний шаг был запущен, но я все еще хочу получать уведомления о промежуточных сбоях, поэтому, если они терпят неудачу последовательно, я могу исследовать.

Ответы [ 7 ]

24 голосов
/ 15 августа 2011

Вот как мы это делаем.Мы добавляем один последний шаг T-SQL (обычно называемый «проверочными шагами») с этим

SELECT  step_name, message
FROM    msdb.dbo.sysjobhistory
WHERE   instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
        AND job_id = $(ESCAPE_SQUOTE(JOBID))
        AND run_status <> 1 -- success

IF      @@ROWCOUNT <> 0
        RAISERROR('Ooops', 16, 1)

Обратите внимание, что этот код использует токены в шагах задания (часть $(...))поэтому код не может быть выполнен в SSMS как есть.Он в основном пытается найти записи о предыдущих шагах текущего задания в sysjobhistory и ищет статусы сбоев.

В Свойствах-> Дополнительно вы также можете проверить Включить вывод шагов в историю , чтобыполучить сообщение от шага сбоя.Оставьте действие При сбое до Выйти из отчета о сбое задания .

3 голосов
/ 01 августа 2014

@ wqw принял превосходный ответ.

Я продлил его для тех, у кого включена функция Database Mail, чтобы отправлять по электронной почте более подробную информацию о том, что именно не удалось и как.Также включает ответ icvader на этой странице, чтобы учесть повторные попытки.

Должно быть действительно полезно для тех из нас, кому нужно больше подробностей, чтобы судить, требуются ли срочные действия при выезде / вызове.

DECLARE 

@YourRecipients as varchar(1000) = 'myadminemail@bloatcorp.com'
,@YourMailProfileName as varchar(255) = 'Database Mail'

,@Msg as varchar(1000)
,@NumofFails as smallint
,@JobName as varchar(1000)
,@Subj as varchar(1000)
,@i as smallint = 1


---------------Fetch List of Step Errors------------
SELECT *
INTO #Errs

FROM

    (
    SELECT 
      rank() over (PARTITION BY step_id ORDER BY step_id) rn
    , ROW_NUMBER() over (partition by step_id order by run_date desc, run_time desc) ReverseTryOrder
    ,j.name job_name
    ,run_status
    , step_id
    , step_name
    , [message]

    FROM    msdb.dbo.sysjobhistory h
    join msdb.dbo.sysjobs j on j.job_id = h.job_id

    WHERE   instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                    WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
            AND h.job_id = $(ESCAPE_SQUOTE(JOBID))
    ) as agg

WHERE ReverseTryOrder = 1 ---Pick the last retry attempt of each step
  AND run_status <> 1 -- show only those that didn't succeed 


SET @NumofFails = ISNULL(@@ROWCOUNT,0)---Stored here because we'll still need the rowcount after it's reset.


-------------------------If there are any failures assemble email and send ------------------------------------------------
IF  @NumofFails <> 0
    BEGIN

        DECLARE @PluralS as char(1) = CASE WHEN @NumofFails > 1 THEN 's' ELSE '' END ---To make it look like a computer knows English
        SELECT top 1 @Subj = 'Job: ' + job_name + ' had ' + CAST(@NumofFails as varchar(3)) + ' step' + @PluralS + ' that failed'
                    ,@Msg =  'The trouble is... ' +CHAR(13) + CHAR(10)+CHAR(13) + CHAR(10)

                        FROM dbo.#Errs


        WHILE @i <= @NumofFails 
        BEGIN
            SELECT @Msg = @Msg + 'Step:' + CAST(step_id as varchar(3)) + ': ' + step_name  +CHAR(13) + CHAR(10)

            + [message] +CHAR(13) + CHAR(10)+CHAR(13) + CHAR(10) FROM dbo.#Errs
            WHERE rn = @i


            SET @i = @i + 1
        END

            exec msdb.dbo.sp_send_dbmail
            @recipients = @YourRecipients,
            @subject = @Subj,
            @profile_name = @YourMailProfileName,
            @body = @Msg


    END

Одно отличие от других ответов, на которых оно основано: не вызывает всю работу как ошибку.Это позволит сохранить различие в истории заданий между прерванными и завершенными ошибками.

2 голосов
/ 07 апреля 2017

Улучшение в ответе выше, в случае, если кто-то хочет использовать операторы в sql server agent для отправки электронной почты; и использовать имя профиля базы данных, сохраненное в msdb:

DECLARE @EmailRecipients as varchar(1000)
DECLARE @MailProfileName as varchar(255)
DECLARE @Msg as varchar(1000)
DECLARE @NumofFails as smallint
DECLARE @JobName as varchar(1000)
DECLARE @Subj as varchar(1000)
DECLARE @i as smallint = 1

SELECT @EmailRecipients = email_address 
FROM msdb.dbo.sysoperators
WHERE name = <Operator Name>

SELECT TOP(1) @MailProfileName = name 
FROM msdb.dbo.sysmail_profile

SELECT * INTO #Errs
FROM
    (SELECT rank() over (PARTITION BY step_id ORDER BY step_id) rn, 
            ROW_NUMBER() over (partition by step_id order by run_date desc, run_time desc) ReverseTryOrder,
           j.name job_name,
           run_status,
           step_id,
           step_name,
           [message]
     FROM msdb.dbo.sysjobhistory h
     JOIN msdb.dbo.sysjobs j ON j.job_id = h.job_id
     WHERE instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                    WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
     AND h.job_id = $(ESCAPE_SQUOTE(JOBID))
    ) AS agg
WHERE ReverseTryOrder = 1 ---Pick the last retry attempt of each step
AND run_status <> 1 -- show only those that didn't succeed 


SET @NumofFails = ISNULL(@@ROWCOUNT,0)---Stored here because we'll still need the rowcount after it's reset.

IF  @NumofFails <> 0
BEGIN
    DECLARE @PluralS as char(1) = CASE WHEN @NumofFails > 1 THEN 's' ELSE '' END

    SELECT top 1 @Subj = job_name + ':'+ CAST(@NumofFails as varchar(3)) + '''Check Steps'' Report',
                 @Msg =  '''Check Steps'' has reported that one or more Steps failed during execution of ' + job_name + CHAR(13) + CHAR(10)+ CHAR(13) + CHAR(10)
    FROM dbo.#Errs

    WHILE @i <= @NumofFails 
    BEGIN
        SELECT @Msg = @Msg + 'Step ' + CAST(step_id as varchar(3)) + ': ' + step_name  +CHAR(13) + CHAR(10)
                     + [message] +CHAR(13) + CHAR(10)+CHAR(13) + CHAR(10) 
        FROM dbo.#Errs
        WHERE rn = @i

        SET @i = @i + 1
    END

    EXEC msdb.dbo.sp_send_dbmail
    @recipients = @EmailRecipients,
    @subject = @Subj,
    @profile_name = @MailProfileName,
    @body = @Msg
END
1 голос
/ 15 апреля 2016

Ответ Адамантиша - идеальное решение (Спасибо): сработало безупречно ... незначительные правки. Как указано ранее в wqw, в SSMS работать не будет, добавьте это в качестве последнего шага и запустите задание.

WHERE instance_id > COALESCE
(
(
SELECT MAX(instance_id) 
FROM msdb.dbo.sysjobhistory
WHERE job_id = '2XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX' AND step_id = 0), 0
)
AND h.job_id = '2XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX'
) 
as agg
1 голос
/ 04 января 2014

Большинство моих шагов настроено на повторную попытку из-за уникального сценария транслога, который иногда вызывает блокировку. Сообщение wqw будет предупреждать, даже если шаг был успешно повторен. Я сделал адаптацию, которая не будет предупреждать, если шаг завершился неудачно, но при повторной попытке был успешным.

SELECT  step_id, MIN(run_status)
FROM    msdb.dbo.sysjobhistory
WHERE   instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
        AND job_id = $(ESCAPE_SQUOTE(JOBID))
GROUP BY step_id
HAVING MIN(run_status) <> 1 -- success

IF @@ROWCOUNT <> 0
RAISERROR('FailedStep', 16, 1)
0 голосов
/ 19 января 2012

на каждом шаге добавьте код:

if @@error > 0
EXEC sp_send_dbmail @profile_name='DBATeam',
@recipients=dbadmin@somewhere.com',
@subject='SomeJob SomeStep failed',
@body='This is the body of SomeJob SomeStep failed' 
0 голосов
/ 05 октября 2010

Перейдите в Свойства задания> вкладка Уведомление> действие, которое нужно выполнить после завершения задания

под этим установите флажок «Электронная почта» и выберите «В случае сбоя задания» из выпадающего списка и сохраните задание.

Читайте 4-й пункт на http://msdn.microsoft.com/en-us/library/ms191130.aspx

Если вы хотите уведомить оператора по электронной почте, проверьте электронную почту, выберите оператора из списка, а затем выберите один из следующих вариантов:

  • Когда задание выполнено успешно: уведомить оператора об успешном завершении задания.

  • При сбое задания: уведомить оператора о неудачном завершении задания.

  • Когда задание завершено: уведомить оператора независимо от статуса завершения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...