Domanda

Can I (Come fare) configurare SQL Server 2008 per notificare un operatore se qualsiasi fase del lavoro viene a mancare?

Ho un processo di SQL Server con diversi passaggi per aggiornare i dati provenienti da più fonti diverse, seguiti da una fase finale che esegue diversi calcoli sui dati. Tutte le "Aggiornamento dati" passaggi sono impostati su "Vai alla fase successiva in caso di errore". In generale, se uno dei rinfresca dati non riesce, voglio ancora il passo finale di corsa, ma ho ancora voglia di essere avvisato sui fallimenti intermedi, quindi se non riescono positiv, posso indagare.

È stato utile?

Soluzione

Ecco come lo facciamo. Aggiungiamo un passo dell'ultimo T-SQL (di solito chiamati "passaggi di controllo") con questo

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)

Si noti che questo codice sta usando token nei passaggi di lavoro (la $(...) parte), quindi codice non possono essere eseguite in SSMS come sono. Si cerca fondamentalmente per trovare le voci di precedenti fasi del lavoro corrente in sysjobhistory e cerca gli stati di errore.

In Properties-> Avanzate è anche possibile controllare Includi uscita passo nella storia per ottenere il messaggio dal fallimento passo. Lasciare il In azione fallimento per Esci il mancato rapporto di lavoro .

Altri suggerimenti

@wqw 's risposta accettata è eccellente.

ho esteso per coloro che hanno Posta elettronica database abilitato alla posta elettronica un po 'più in dettaglio su ciò che non è riuscito e come. incorpora anche la risposta di icvader in questa pagina, per tener conto di tentativi.

Dovrebbe essere molto utile per quelli di noi che hanno bisogno di maggiore dettaglio per giudicare se sia necessaria un'azione urgente quando fuori sede / a chiamata.

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

Una differenza dalle altre risposte su cui ha basato la sua: non solleva tutto il lavoro come un errore. Quella di mantenere la distinzione nella cronologia dei lavori tra l'annullate e completata con errori.

Un miglioramento alla risposta di cui sopra, nel caso in cui qualcuno vuole utilizzare gli operatori di agente di SQL Server per inviare e-mail; e utilizzare il nome del profilo del database memorizzato in 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

Ho la maggior parte dei miei passi impostati per riprovare a causa di uno scenario translog unico che provoca il blocco occasionale. Il post di wqw avviserà anche se un passo è riprovato con successo. Ho fatto un adattamento che non sarà avviso se un passo è fallito, ma poi è stato un successo sul tentativo.

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)

La risposta di Adamantish è la soluzione perfetta (Grazie): funzionato senza problemi .. modifiche minori. Come wqw detto prima, non funziona in SQL Server Management Studio, aggiungere questo come ultimo passo ed eseguire il lavoro.

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

Vai alla Proprietà del lavoro> scheda Notifica> azione da eseguire quando il lavoro è stato completato

sotto controllo che la casella di controllo e-mail e selezionare "Quando il lavoro viene a mancare" dal menu a discesa e salvare il lavoro.

Leggi punto 4 sulla http://msdn.microsoft.com/en- us / library / ms191130.aspx

Se si desidera informare un operatore via e-mail, controllare la posta elettronica, selezionare un operatore dall'elenco, quindi selezionare una delle seguenti:

  • Quando il lavoro riesce:. Per avvisare l'operatore quando il completamento del lavoro con successo

  • Quando il lavoro non viene:. Per avvisare l'operatore quando il completamento del lavoro senza successo

  • Quando il completamento del lavoro:. Per segnalare all'operatore indipendentemente dallo status di completamento

in ogni codice passaggio aggiuntivo:

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' 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top