18

ジョブのいずれかのステップが失敗した場合にオペレーターに通知するようにSQLServer2008を構成できますか(方法)?

複数の異なるソースからのデータを更新するためのいくつかのステップと、それに続くデータに対していくつかの計算を実行する1つの最後のステップを含むSQLServerジョブがあります。すべての「データ更新」ステップは、「障害時に次のステップに進む」に設定されています。一般的に、データの更新の1つが失敗した場合でも、最後のステップを実行したいのですが、中間の失敗について通知を受けたいので、一貫して失敗した場合は調査できます。

4

7 に答える 7

32

これが私たちのやり方です。これで最後の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し、失敗ステータスを探します。

[プロパティ]->[詳細設定]で、[履歴にステップ出力を含める]をオンにして、ステップの失敗からメッセージを取得することもできます。[失敗時]アクションをそのままにして、失敗を報告するジョブを終了します。

于 2011-08-15T11:11:40.960 に答える
4

@wqwの受け入れられた答えは素晴らしいです。

データベースメールを有効にしている人のために、何がどのように失敗したかについてもう少し詳細を電子メールで送信できるように拡張しました。また、再試行を考慮して、このページに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

それが基づいている他の答えとの1つの違い:エラーとして仕事全体を上げません。これは、ジョブ履歴でAbortedとCompletedwithErrorsの区別を維持するためです。

于 2014-08-01T17:46:36.520 に答える
3

ときどきブロックされる独自のトランスログシナリオのため、ほとんどの手順を再試行するように設定しています。ステップが正常に再試行された場合でも、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)
于 2014-01-04T04:47:35.413 に答える
3

誰かがSQLサーバーエージェントの演算子を使用して電子メールを送信したい場合の上記の回答の改善。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
于 2017-04-07T06:26:28.740 に答える
1

Adamantishの答えは完璧な解決策です(ありがとう):完璧に機能しました..マイナーな編集。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
于 2016-04-15T00:57:24.093 に答える
0

[ジョブのプロパティ]>[通知]タブ>[アクション]に移動して、ジョブの完了時に実行します

その下の[メール]チェックボックスをオンにし、ドロップダウンから[ジョブが失敗したとき]を選択して、ジョブを保存します。

http://msdn.microsoft.com/en-us/library/ms191130.aspxで4番目のポイントを読む

電子メールでオペレーターに通知する場合は、電子メールをチェックし、リストからオペレーターを選択してから、次のいずれかを選択します。

  • ジョブが成功した場合:ジョブが正常に完了したときにオペレーターに通知します。

  • ジョブが失敗した場合:ジョブが失敗したときにオペレーターに通知します。

  • ジョブが完了したとき:完了ステータスに関係なくオペレーターに通知します。

于 2010-10-04T20:45:24.580 に答える
0

各ステップでコードを追加します。

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' 
于 2012-01-19T09:26:37.580 に答える