2012-05-25 10 views
14

Sto cercando di sviluppare un trigger di posta. Qualcuno potrebbe assistere su come questo potrebbe essere raggiunto in modo che quando un uso inserisce un record controlla il campo "velocità" in modo tale che quando il valore inserito supera 100, una mail viene inviata all'indirizzo specificato.Invia e-mail da un trigger

+0

È inoltre necessario ESEGUI l'utente per msdb.dbo.sp_send_dbmail, ad esempio se è in esecuzione in un'app. – smoore4

risposta

37

Per prima cosa è necessario impostare la posta del database - se non l'hai fatto, a questa domanda potrebbe aiutare:

allora avete bisogno di un trigger:

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 

Ora, probabilmente stai per dire che vuoi che i dati dall'inserto siano effettivamente inclusi nell'e-mail. E la tua prima inclinazione sarà quella di dichiarare alcune variabili locali e assegnarle da inserted - questo non funziona perché il trigger potrebbe rispondere a un inserto multi-riga. Quindi il modo giusto per fare questo è:

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 

Che tutti Detto questo, io non sono un grande fan di invio di e-mail da un trigger. Anche se la posta del database utilizza il broker di servizi e quindi è asincrona, sarei molto più incline a popolare una tabella di code, e ho un thread in background che viene fornito e invia tutte le e-mail appropriate. I due tre cose belle di questo sono:

  1. a ridurre al minimo i potenziali ritardi nel commettere la transazione esterna che ha attivato il trigger - più complicata la logica nel trigger, il più lento fate quel processo.
  2. poiché probabilmente non è essenziale che l'e-mail sia inviata il microsecondo in cui è inserita la riga, è possibile fluttuare facilmente i tempi del processo in background - questo evita di dover controllare il tavolo molto minuto, tutto il giorno, quando pochissimi volte dovrà mai fare effettivamente qualcosa.
  3. Come sottolineato da @goodeye, mantenere questo processo separato può impedire che errori nella parte di posta elettronica del processo interferiscano con il DML originale (nel loro caso, un parametro non valido su sp_send_dbmail - che inavvertitamente ho suggerito - ha impedito l'inserimento).
+0

Grazie per il feedback. Come configuro la posta del database. –

+1

+1 per "Sì, erano sicuri". – JNK

+0

Grazie. La soluzione funziona bene –