Question

Can I (Comment puis-je) configure Sql Server 2008 pour notifier un opérateur si une étape du travail échoue?

I ai un travail SQL Server avec plusieurs étapes de mise à jour des données provenant de multiples sources différentes, suivie par une étape finale qui effectue plusieurs calculs sur les données. Toutes les « actualisation des données » étapes sont à « Passez à l'étape suivante en cas d'échec ». D'une manière générale, si l'une des données rafraîchi échoue, je veux encore la dernière étape à courir, mais je veux encore être informé au sujet des pannes intermédiaires, donc si elles ne parviennent pas consistantly, je peux enquêter.

Était-ce utile?

La solution

Voici comment nous le faisons. Nous ajoutons une dernière étape T-SQL (communément appelées « étapes de contrôle ») avec cette

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)

Notez que ce code utilise dans les étapes d'emploi (la partie $(...)), de sorte que le code ne peut être exécuté dans SSMS comme il est. Il essaie basiquement de trouver les entrées des étapes précédentes de la tâche en cours dans sysjobhistory et recherche des statuts d'échec.

Dans Propriétés-> Avancé, vous pouvez également vérifier Inclure la sortie de l'étape dans l'histoire pour obtenir le message de l'échec de l'étape. Laissez le sur l'action d'échec Quitter l'échec de rapports d'emploi .

Autres conseils

@wqw « s réponse acceptée est excellente.

Je l'ai étendu pour ceux qui ont permis de messagerie de base par courriel un peu plus de détails sur exactement ce qui a échoué et comment. Intègre également la réponse de icvader sur cette page pour tenir compte de réitérations.

devrait être très utile pour ceux d'entre nous qui ont besoin de plus de détails pour juger si une action urgente est nécessaire lorsque hors site / sur appel.

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

Une différence des autres réponses sur lesquelles sa base: ne soulève pas tout le travail comme une erreur. C'est de conserver la distinction dans l'histoire de l'emploi entre Aborted et terminée avec des erreurs.

Une amélioration de la réponse ci-dessus, cas où quelqu'un veut utiliser les opérateurs agent serveur SQL pour envoyer un courriel; et utiliser le nom du profil de base de données stockées dans 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

J'ai la plupart de mes pas mis à nouvelle tentative en raison d'un scénario translogarithmique unique qui provoque le blocage occasionnel. Le poste de wqw alertera même si une étape a avec succès une nouvelle tentative. J'ai fait une adaptation qui ne sera pas alerte si une étape a échoué, mais a été un succès sur nouvelle tentative.

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 réponse de Adamantish est la solution parfaite (Merci): a parfaitement fonctionné .. modifications mineures. Comme indiqué précédemment wqw, ne fonctionnera pas dans SSMS, ajoutez une dernière étape et exécuter la tâche.

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

Aller à Propriétés d'emploi> onglet Notification> action à effectuer lorsque le travail est terminé

sous le cocher la case E-mail et sélectionnez « Quand le travail échoue » dans le menu déroulant et enregistrer le travail.

Lire 4ème point http://msdn.microsoft.com/en- nous / bibliothèque / ms191130.aspx

Si vous souhaitez notifier un opérateur par e-mail, consultez E-mail, sélectionnez un opérateur dans la liste, puis sélectionnez l'une des options suivantes:

  • Quand le travail réussit. D'informer l'opérateur lorsque le travail est terminé avec succès

  • Quand le travail échoue. D'informer l'opérateur lorsque le travail est terminé sans succès

  • Quand le travail est terminé:. D'aviser l'opérateur quel que soit l'état d'achèvement

dans chaque code add étape:

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' 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top