web-dev-qa-db-fra.com

Envoyer un e-mail à partir d'un déclencheur

J'essaie de développer un déclencheur de messagerie. Quelqu'un pourrait-il aider sur la façon dont cela pourrait être réalisé afin que lorsqu'une utilisation insère un enregistrement, il vérifie le champ "vitesse" de telle sorte que lorsque la valeur insérée dépasse 100, un courrier est envoyé à l'adresse spécifiée.

19
James Obuhuma

Vous devez d'abord configurer la messagerie de la base de données - si vous ne l'avez pas encore fait, cette question pourrait vous aider:

Ensuite, vous avez besoin d'un déclencheur:

CREATE TRIGGER dbo.whatever
ON dbo.wherever
FOR INSERT
AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (SELECT 1 FROM inserted WHERE speed > 100)
    BEGIN
        EXEC msdb.dbo.sp_send_dbmail
          @recipients = '[email protected]', 
          @profile_name = 'default',
          @subject = 'Someone was speeding', 
          @body = 'Yep, they sure were.';
    END
END
GO

Maintenant, vous allez probablement dire que vous souhaitez que les données de l'encart soient réellement incluses dans l'e-mail. Et votre première inclinaison va être de déclarer des variables locales et de les affecter à partir de inserted - cela ne fonctionne pas car votre déclencheur pourrait répondre à un insert à plusieurs lignes. La bonne façon de procéder est donc:

CREATE TRIGGER dbo.whatever
ON dbo.wherever
FOR INSERT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @body NVARCHAR(MAX) = N'';

    SELECT @body += CHAR(13) + CHAR(10) + RTRIM(some_col) FROM inserted;

    IF EXISTS (SELECT 1 FROM inserted WHERE speed > 100)
    BEGIN
        EXEC msdb.dbo.sp_send_dbmail
          @recipients = '[email protected]', 
          @profile_name = 'default',
          @subject = 'At least one person was speeding', 
          @body = @body;
    END
END
GO

Cela dit, je ne suis pas un grand fan de l'envoi d'e-mails à partir d'un déclencheur. Même si le courrier de la base de données utilise Service Broker et est donc asynchrone, je serais beaucoup plus enclin à remplir une table de file d'attente et à avoir un fil d'arrière-plan qui revient et envoie tous les e-mails appropriés. le deuxtrois bonnes choses à ce sujet sont:

  1. vous minimisez les retards potentiels dans la validation de la transaction externe qui a déclenché le déclencheur - plus votre logique est compliquée dans le déclencheur, plus vous ralentissez ce processus.
  2. comme il n'est probablement pas essentiel que l'e-mail soit envoyé la microseconde où la ligne est insérée, vous pouvez facilement faire varier le timing du processus d'arrière-plan - cela évite d'avoir à vérifier le tableau très minute, toute la journée, quand très peu de fois jamais avoir à faire quoi que ce soit.
  3. Comme l'a souligné @goodeye, la séparation de ce processus peut empêcher des erreurs dans la partie e-mail du processus d'interférer avec le DML d'origine (dans leur cas, un paramètre non valide pour sp_send_dbmail - que j'ai suggéré par inadvertance - a empêché l'insertion).
49
Aaron Bertrand