Create a Basic SQL Server 2005 Trigger to Send E-mail Alerts

Filed under: Quick Code, SQL Server — Written by Chrissy on Tuesday, February 5th, 2008 @ 11:07 am

For as many times as I have read about sending e-mails using SQL Server triggers, I've rarely come across actual code samples. After someone asked for a "Triggers for Dummies" example in a Facebook SQL group, I created the following example which uses a trigger to alert a manager that an expensive item has been entered into inventory.

First, if SQL Mail isn't enabled and a profile hasn't been created, we must do so.

Enable SQL Mail/Create Profile

--// First, enable SQL SMail
use master
go
sp_configure 'show advanced options',1
go
reconfigure with override
go
sp_configure 'Database Mail XPs',1
go
reconfigure
go
 
--//Now create the mail profile. CHANGE @email_address,@display_name and @mailserver_name VALUES to support your environment
EXECUTE msdb.dbo.sysmail_add_account_sp
@account_name = 'DBMailAccount',
@email_address = 'sqlserver@domain.com',
@display_name = 'SQL Server Mailer',
@mailserver_name = 'exchangeServer'
 
EXECUTE msdb.dbo.sysmail_add_profile_sp
@profile_name = 'DBMailProfile'
 
EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
@profile_name = 'DBMailProfile',
@account_name = 'DBMailAccount',
@sequence_number = 1 ;

Now that SQL will support sending e-mails, let's create the sample table. This is not a useful or well designed table by any means -- it's just a simple example table:

CREATE TABLE

CREATE TABLE dbo.inventory (
item varchar(50),
price money
)
GO

Now that SQL mail and the table are setup, we will create a trigger that does the following:

  • Creates an AFTER INSERT trigger named expensiveInventoryMailer on the inventory table. This means that the trigger will be executed after the data has been entered.
  • Checks for items being entered that have a price of $1000 or more
  • If there is a match, an email is sent using the SQL Mail profile we used above.

The Actual Trigger

CREATE TRIGGER expensiveInventoryMailer ON dbo.inventory AFTER INSERT AS
 
DECLARE @price money
DECLARE @item varchar(50)
 
SET @price  = (SELECT price FROM inserted)
SET @item = (SELECT item FROM inserted)
 
IF @price >= 1000
  BEGIN
    DECLARE @msg varchar(500)
    SET @msg = 'Expensive item "' + @item + '" entered into inventory at $' + CAST(@price as varchar(10)) + '.'
    --// CHANGE THE VALUE FOR @recipients
    EXEC msdb.dbo.sp_send_dbmail @recipients=N'manager@domain.com', @body= @msg,  @subject = 'SQL Server Trigger Mail', @profile_name = 'DBMailProfile'
  END
GO

The only way to test a trigger is to add actual data, so let's do that here:
insert into inventory (item,price) values ('Vase',100)
insert into inventory (item,price) values ('Oven',1000)

Your email should arrive very quickly. If it doesn't, check the SQL Server mail log in SQL Management Studio by running SELECT * FROM sysmail_allitems.

Have fun!

25 Comments   -
  • Pingback Plain code | Sending mail from sql server 2005 | July 2, 2008 @ 11:35 am

    [...] myst try this out: Sending mail from sql server trigger [...]

  • Comment by Bryden | July 23, 2008 @ 10:12 am

    Thank you

    nice and simple allowed me use create my own variation in a
    couple of minutes

  • Comment by Chris B. | September 30, 2008 @ 6:01 pm

    Thanks Crissy! This example was exactly what I needed...I just wasted 20 minutes on MSDN site...wish I'd found this sooner.

  • Comment by Kimberly | October 7, 2008 @ 10:30 pm

    It worked great!!! Thank you so much

  • Comment by Balasubramaniam K | October 19, 2008 @ 9:39 am

    Thanks a lot ! The concept was superbly explained and was very useful for me.

  • Comment by darshan thacker | November 2, 2008 @ 12:03 pm

    hie...
    m not getting sent mail from my db.
    its giving me exception
    "The mail could not be sent to the recipients because of the mail server failure. (Sending Mail using Account 2 (2007-03-08T00:49:29). Exception Message: Could not connect to mail server. (No connection could be made because the target machine actively refused it)."

  • Comment by Lalit Kumar | November 16, 2008 @ 10:56 am

    I need some more clarification.

  • Comment by sihua | March 5, 2009 @ 1:48 pm

    Thanks, worked for my project too. Nice clean code. Thanks!

  • Comment by sam | March 7, 2009 @ 11:53 am

    hi i tried it and working 100 %

    but how to create a trigger mail after delete or update?

  • Comment by dabigo | March 7, 2009 @ 5:51 pm

    This was great, thanks.

  • Comment by jakech | March 9, 2009 @ 4:10 am

    Great.
    Works fine

  • Comment by Chrissy | March 13, 2009 @ 8:23 pm

    Hey Sam,
    Just do INSTEAD OF UPDATE or INSTEAD OF DELETE in the place of INSTEAD OF INSERT.

    That should do the trick.

  • Comment by Priya | March 15, 2009 @ 7:24 am

    Please tell me what is wrong with my code:
    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go

    -- =============================================
    -- Author:
    -- Create date:
    -- Description:
    -- =============================================
    ALTER TRIGGER [BirthdayMailer] ON [dbo].[Employee] FOR UPDATE
    AS

    DECLARE @BD varchar(50)
    DeCLARE @FN VARCHAR(50)

    SET @BD = (SELECT Birthdate FROM inserted)
    SET @FN = (SELECT FirstName FROM inserted)

    IF @FN = 'Priya'
    BEGIN
    DECLARE @msg varchar(500)
    SET @msg = 'Upcoming Birthday "' + @BD + '" .Please check your database for more information'

    EXEC msdb.dbo.sp_send_dbmail @recipients= 'h@y.com', @body= @msg, @subject = 'SQL Server Trigger Mail', @profile_name = 'TAlerts'
    END

    I get error near inserted.

  • Comment by Matt | March 20, 2009 @ 10:33 am

    Thanks, Nice and easy.

  • Comment by shep | March 24, 2009 @ 3:15 pm

    Thanks, here are some debugging queries:

    --check to see if service broker is enabled
    --SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb' ;

    --check to see if database mail is started in msdb database
    --use msdb go EXECUTE dbo.sysmail_help_status_sp ;

    --start database mail if necessary
    --EXECUTE dbo.sysmail_start_sp ;

    --check status of mail queue
    --sysmail_help_queue_sp @queue_type = 'Mail' ;

    --check database mail event log
    --use msdb select * from sysmail_event_log

    --check database mail queue for status of all items
    -- use msdb select * from sysmail_allitems

  • Comment by NEFI | April 15, 2009 @ 6:16 pm

    Hey Guys
    I have problem sending mail, it doesn't work, It runs but it dont sent
    this is my cofiguration:
    EXECUTE msdb.dbo.sysmail_add_account_sp
    @account_name = 'DBMailAccount',
    @email_address = 'nefihumberto@gmail.com',
    @display_name = 'SQL Server Mailer',
    @mailserver_name = 'smtp.gmail.com'

  • Comment by NEFI | April 15, 2009 @ 6:17 pm

    I'm working with SQL EXPRESS,is it the problem?

  • Comment by Maksuda | April 28, 2009 @ 12:13 pm

    Hi:
    I tried the above code but no mail was sent.
    From Log file I got the error message -
    Could not connect to mail server. (No connection could be made because the target machine actively refused it 10.20.30.40:25).
    4/24/2009 2:36:34 PM,sa

    pls need help. I badly need help..........stuck here......pls.......

  • Comment by Ram | April 29, 2009 @ 4:36 am

    Thanks Nice and easy

  • Comment by Lili | May 22, 2009 @ 6:42 am

    Is there an easy way to put conditions into the trigger? Like If a field = something send the email to emailgroup1 and if field=something else send the email to emailgroup2?

  • Comment by Nathan Coson | May 24, 2009 @ 5:58 pm

    I keep getting a retrying/failed status. never tries to cmmunicate with the local mail that is programmed.
    EXECUTE msdb.dbo.sysmail_add_account_sp
    @account_name = 'SQLTest3',
    @email_address = 'nathan@corsons.net',
    @display_name = 'SQL Server Mailer',
    @mailserver_name = '192.168.1.101'

    EXECUTE msdb.dbo.sysmail_add_profile_sp
    @profile_name = 'SQLTest3'

    EXECUTE msdb.dbo.sysmail_add_profileaccount_sp
    @profile_name = 'SQLTest3',
    @account_name = 'nathan@corsons.net',
    @sequence_number = 1 ;

    The query also states

    Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
    Configuration option 'Database Mail XPs' changed from 1 to 1. Run the RECONFIGURE statement to install.

    Any ideas?

  • Comment by Nathan Corson | May 24, 2009 @ 9:33 pm

    OK got it to work but thru a test mail server that doesnt need authentication. How do i specify authentication for username and password? Thanks

  • Comment by Nathan Corson | May 24, 2009 @ 9:39 pm

    OK got it to work but thru a test mail server that doesnt need authentication. How do i specify authentication for username and password? Also, is it possible to pull the email to send it to from a field in a separate table rather than be hard coded in the trigger? Thanks

  • Comment by henry | June 8, 2009 @ 10:10 am

    this is what I need:

    a trigger to pass data from the table to an url address (to pass data from database to another database) I will be coping the information of 5, 6 fields; Can you help me ???

    I will pay for your services.

    thanks a lot

  • Comment by Dennis Hatcher | June 15, 2009 @ 1:46 pm

    Excellent. May want to mention that the sysmail_allitems is in the msdb database. I just added the server to the select statement.

    SELECT 'sysmail_sentitems' as TableName, * FROM msdb.dbo.sysmail_sentitems

    SELECT 'sysmail_faileditems' as TableName, * FROM msdb.dbo.sysmail_faileditems

    SELECT 'sysmail_allitems' as TableName, * FROM msdb.dbo.sysmail_allitems

    SELECT 'sysmail_unsentitems' as TableName, * FROM msdb.dbo.sysmail_unsentitems

    SELECT 'sysmail_mailattachments' as TableName, * FROM msdb.dbo.sysmail_mailattachments

Leave your comment