Отправить письмо из триггера

Я пытаюсь разработать почтовый триггер. Может ли кто-нибудь помочь с тем, как этого можно добиться, чтобы при использовании пользователем вставки записи он проверял поле "скорость", чтобы при вставленном значении превышать 100 отправлялось письмо по указанному адресу.

1 ответ

Решение

Сначала вам нужно настроить почту базы данных - если вы этого не сделали, этот вопрос может помочь:

Тогда вам нужен триггер:

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 = 'whoever@yourcompany.com', 
          @profile_name = 'default',
          @subject = 'Someone was speeding', 
          @body = 'Yep, they sure were.';
    END
END
GO

Теперь вы, вероятно, скажете, что хотите, чтобы данные из вставки были фактически включены в электронное письмо. И ваша первая склонность будет объявить некоторые локальные переменные и назначить их из inserted - это не работает, потому что ваш триггер может отвечать на многорядную вставку. Итак, правильный способ сделать это:

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 = 'whoever@yourcompany.com', 
          @profile_name = 'default',
          @subject = 'At least one person was speeding', 
          @body = @body;
    END
END
GO

Тем не менее, я не большой поклонник отправки электронной почты из триггера. Несмотря на то, что база данных почты использует сервисный брокер и поэтому является асинхронной, я был бы гораздо более склонен заполнять таблицу очередей и иметь фоновый поток, который приходит и отправляет все соответствующие электронные письма. Две три хороших вещи об этом:

  1. Вы сводите к минимуму потенциальные задержки при совершении внешней транзакции, которая сработала триггером - чем сложнее ваша логика в триггере, тем медленнее вы выполняете этот процесс.
  2. так как, вероятно, не обязательно, чтобы электронное письмо отправлялось за микросекунду, в которую вставлена ​​строка, вы можете легко изменить время фонового процесса - это позволяет избежать необходимости проверять таблицу очень мелко, весь день, когда очень мало раз она будет когда-либо нужно на самом деле делать что-нибудь.
  3. Как отметил @goodeye, сохранение этого процесса отдельным может предотвратить ошибки в части процесса, связанной с электронной почтой, от вмешательства в исходный DML (в их случае недопустимый параметр для sp_send_dbmail - что я непреднамеренно предложил - помешала вставка).
Другие вопросы по тегам