【问题标题】:SQL Trigger to send an email用于发送电子邮件的 SQL 触发器
【发布时间】:2017-02-03 05:25:54
【问题描述】:

如果插入的记录满足某些条件,我需要在 SQL 表中创建触发器以发送电子邮件。 也就是说,如果在插入的记录中字段 IdCircuito= 53、IdTipoDoc = 45 和 Gestor = 'Gest1',我会在 Table1 中创建触发器以向 X 发送电子邮件。此外,在电子邮件正文中,我希望显示该插入记录的某个字段的值。我做过这样的事情,但无论插入的记录如何,触发器都会执行:

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 = 'rsg@gmail.com', 
      @subject = 'New requeriment', 
      @body = 'It's a new requeriment: ';
END
END
GO

在正文中,我想显示带有插入记录字段值的文字文本: @body = '这是一个新的要求:' + TitulosDoc.NombreDocumento;

有人可以帮助我吗?谢谢

【问题讨论】:

  • 与其直接从触发器发送电子邮件,不如填充需要通过电子邮件发送的数据的临时表。然后创建一个进程,每隔几分钟查询一次临时表并发送电子邮件。这里的基本原理是因为您一次可以插入超过 1 行,并且您需要循环这些行。我们没有将循环和电子邮件放入您的触发器中,而是将其移至临时表以保持系统的性能。

标签: sql-server tsql triggers


【解决方案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 = 'rsg@gmail.com', 
      @subject = 'New requeriment', 
      @body = 'It''s a new requeriment: ' + @NombreDocumento;
END
END
GO

【讨论】:

  • 由于我们可以插入多行,这是需要循环的时候之一。
  • 感谢@Stephen!。您的答案对我有用,但稍作修改:在 body 变量中,您不能以这种方式将文字文本与变量连接,您必须这样做: set @body = 'It's a new requeriment: ' + (从插入中选择 NombreDocumento);
【解决方案2】:

我会按照 Sean 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 = 'rsg@gmail.com', 
          @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 teq.@EmailStatus = 1
        FROM dbo.TempTiulosDoc teq
        WHERE teq.id = @field1

        SET @loopCount = @loopCount + 1

    END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    相关资源
    最近更新 更多