2012-05-25 155 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

謝謝。你的解決方案工作正常 –