2012-05-25 158 views
14

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

+0

如果msdb.dbo.sp_send_dbmail运行在应用中,您还需要为用户授予EXECUTE。 – smoore4

回答

37

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

然后,你需要一个触发:

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 

现在,您可能会说,您希望插入的数据实际上包含在电子邮件中。你的第一个倾向将是声明一些局部变量,并从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 = '[email protected]', 
      @profile_name = 'default', 
      @subject = 'At least one person was speeding', 
      @body = @body; 
    END 
END 
GO 

这一切都说,我不是从触发器发送电子邮件的大扇子。即使数据库邮件使用服务代理,因此也是异步的,但我更倾向于填充队列表,并有一个后台线程来发送并发送所有适当的电子邮件。关于这个 3的好东西是:

  1. 您最大限度地减少在提交触发触发器外部事务的潜在延迟 - 更复杂的在触发逻辑,慢你作出这样的过程。
  2. 因为发送电子邮件可能并不是必要的,所以在插入行时微秒,您可以轻松地调整后台进程的时间 - 这样可以避免必须在非常少的时间它将永远不得不做任何事情。
  3. 作为@goodeye指出的那样,保持此过程分开,能够防止在该方法的电子邮件部分误差从与所述原始DML干扰(在他们的情况下,为了sp_send_dbmail无效的参数 - 我建议无意中 - 防止插入)。
+0

感谢您的反馈。如何设置数据库邮件。 '是的,他们当然是。' –

+1

+1。 – JNK

+0

谢谢。你的解决方案工作正常 –