2017-02-02 2 views
1

Мне нужно создать триггер в таблице SQL для отправки электронной почты, если вставленная запись соответствует определенным условиям. То есть я создаю триггер в таблице1, чтобы отправить электронное письмо на X, если во вставленной записи поле IdCircuito = 53, IdTipoDoc = 45 и Gestor = 'Gest1'. Кроме того, в теле сообщения электронной почты я хочу, чтобы появилось значение определенного поля этой вставленной записи. Я сделал что-то вроде этого, но триггер всегда выполняет независимо от вставленной записи:SQL Trigger для отправки электронной почты

CREATE TRIGGER dbo.SendEmail 
    ON dbo.TitulosDoc 
    AFTER INSERT 
AS 

BEGIN   
SET NOCOUNT ON; 
IF EXISTS (SELECT 1 FROM TitulosDoc WHERE IdCircuito = 53 AND IdTipoDoc = 45 AND Gestor = 'Gest1') 
BEGIN 
    EXEC msdb.dbo.sp_send_dbmail 
     @recipients = '[email protected]', 
     @subject = 'New requeriment', 
     @body = 'It's a new requeriment: '; 
END 
END 
GO 

В теле, где я хочу показать буквальный текст со значением поля вставленной записи: @body = «Это новый запрос: '+ TitulosDoc.NombreDocumento;

Может кто-нибудь мне помочь? Спасибо

+0

Вместо отправки электронной почты непосредственно с вашего триггера вместо этого необходимо заполнить промежуточную таблицу данных, которую необходимо отправить по электронной почте. Затем создайте процесс, который запрашивает промежуточную таблицу каждые несколько минут и отправляет электронное письмо. Обоснование здесь состоит в том, что вы можете добавить более одной строки за раз, и вам нужно будет зациклировать эти строки. Вместо того, чтобы вводить петли и электронные письма в ваш триггер, мы перемещаем это в промежуточную таблицу, чтобы поддерживать производительность системы. –

ответ

1

Для доступа к вставленной строке вам нужно выбрать INSERTED. Попробуйте это:

CREATE TRIGGER dbo.SendEmail 
    ON dbo.TitulosDoc 
    AFTER INSERT 
AS 

BEGIN   
SET NOCOUNT ON; 

DECLARE @NombreDocumento VARCHAR(MAX) = (SELECT INSERTED.NombreDocumento 
             FROM INSERTED 
             WHERE INSERTED.IdCircuito = 53 
             AND INSERTED.IdTipoDoc = 45 
             AND INSERTED.Gestor = 'Gest1') 

IF @NombreDocumento IS NOT NULL 
BEGIN 

    EXEC msdb.dbo.sp_send_dbmail 
     @recipients = '[email protected]', 
     @subject = 'New requeriment', 
     @body = 'It''s a new requeriment: ' + @NombreDocumento; 
END 
END 
GO 
+0

Поскольку мы можем получить несколько строк в вставленном, это одно из тех случаев, когда требуется цикл. –

+0

Спасибо @Stephen !. Ваш ответ работает на меня, но с небольшой модификацией: в переменной body вы не можете конкатенировать буквальный текст с переменной таким образом, вы должны сделать это: set @body = 'It''sa new requeriment:' + (выберите NombreDocumento из вставленного); – Rsg

0

Я хотел бы сделать то, что сказал Шон Lange ... создать физическую таблицу под названием TempTitulosDoc, а затем вставить свои записи в нем, которые должны быть отправлены по электронной почте. Сделайте это в своем триггере.

CREATE TRIGGER dbo.SendEmail 
    ON dbo.TitulosDoc 
    AFTER INSERT 
AS 

BEGIN   
SET NOCOUNT ON; 
BEGIN 

    INSERT INTO TempTiulosDoc(field1, field2, EmailStatus) 
    SELECT field1, field2, 0 AS EmailStatus --Email NOT sent 
    FROM TitulosDoc 
    WHERE IdCircuito = 53 AND IdTipoDoc = 45 AND Gestor = 'Gest1' 

END 
END 
GO 

Создайте хранимую процедуру, подобную этой, которая проходит через эти записи и отправляет электронное письмо. Когда это будет сделано, обновите TempTitlosDoc со статусом 1, обозначающим отправленное электронное письмо.

DECLARE @loopCount  INT 
DECLARE @field1   VARCHAR(10) 
DECLARE @field2   VARCHAR(10) 
DECLARE @EmailStatus int 

--Create Temp Table 
CREATE TABLE #Temp 
(
    id int not null identity, 
    field1 VARCHAR(10), 
    field2 VARCHAR(10), 
    EmailStatus int 
) 

--Insert Tasks to temp table 
INSERT INTO #Temp (field1, field2, EmailStatus) 
SELECT field1, field2, EmailStatus 
FROM dbo.TempTiulosDoc 
WHERE Status = 0 

--Set a loopCount for while loop 
SET @loopCount = 1 

--Use the while loop to check if we have any Tasks left to send 
while (exists(SELECT id FROM #Temp WHERE id = @loopCount)) 
    BEGIN 

     --Get current record in temp table 
     SELECT @field1    = field1, 
       @field2    = field2, 
       @EmailStatus  = EmailStatus 
     FROM #Temp 
     WHERE id = @loopCount 

     EXEC msdb.dbo.sp_send_dbmail 
      @recipients = '[email protected]', 
      @subject = 'New requeriment', 
      @body = 'It''s a new requeriment: ' + @NombreDocumento; 

     --Update your work table with the status of 1 so it's not picked up again 
     UPDATE teq 
     SET [email protected] = 1 
     FROM dbo.TempTiulosDoc teq 
     WHERE teq.id = @field1 

     SET @loopCount = @loopCount + 1 

    END 
+0

Отличная альтернатива! Спасибо, господин – Rsg

Смежные вопросы