从触发器发送电子邮件

时间:2012-05-25 13:42:43

标签: email triggers sql-server-2008-r2

我正在尝试开发邮件触发器。有人可以协助如何实现这一点,以便当用户插入记录时,它会检查“速度”字段,以便当插入的值超过100时,将邮件发送到指定的地址。

1 个答案:

答案 0 :(得分:49)

首先,您需要设置数据库邮件 - 如果您还没有这样做,这个问题可能会有所帮助:

然后你需要一个触发器:

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的无效参数 - 这是我无意中建议的 - 阻止插入。)