When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips

Sections:
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
XML Info
Information:
Feedback
Author an Article
ASP ASP.NET ASP FAQs Message Board Feedback
Print this page.
User Tips: Receiving an Email When Database Data is Changed


By Wade Wilbur

For low-volume databases, those that are predominantly read and not written to, or database tables that are designed to not be updated or only updated under rare circumstances, a DBA or developer may be interested in being notified whenever the data in a particular table is modified. Or you may have certain records in a table that are assigned to a particular user and, upon that record being updated, that user should be notified of the change. While this sort of logic can be implemented at the code level, Microsoft SQL Server has all of the technologies needed to achieve this aim built directly into it. Triggers can be used to perform some action when data is inserted, updated, or deleted from a table, and Microsoft SQL Server's xp_sendmail extended stored procedure can be invoked to send an email to one or more recipients. Combining triggers with xp_sendmail provides a means for alerting specified users via email when the data in a particular table is modified.

The purpose of this article is to demonstrate how to create such a notification system. This code presented here is a simplified version from an action item application that emails the appropriate people when an item is updated. I noticed that some of my staff who were just learning SQL were intimidated by triggers and SQL Mail, so I wanted to come up with an example which was useful, yet easy to follow.

In this article we'll step through creating the table, some dummy data, and the trigger one step at a time. You can download the entire database script at the end of this article.

Creating the Table and Populating it with a Test Record
Let's start by creating a table which will hold comments that need to be updated:

CREATE TABLE tstComments (
   CommentID int IDENTITY(1,1),
   ActionItemID int,
   CommentDate datetime,
   CommentText varchar(100)
)
GO

Next we'll insert a row to update:

insert into tstComments(ActionItemID, CommentDate, CommentText)
values('1','5/5/06','this is the original comment')

Creating the Trigger
Now we create the trigger for the tstComments table. Before we create the trigger, however, we should first see if the trigger already exists and, if so, delete it. This can be accomplished by checking the sysobjects table to see if a trigger with the specified name exists. If so, we can delete it by using the DROP TRIGGER keyword.

-- Drop the trigger if it already exists
IF EXISTS(
      SELECT * 
      FROM dbo.sysobjects 
      WHERE id = object_id(N'[updComments]') AND 
            OBJECTPROPERTY(id, N'IsTrigger') = 1)
  DROP TRIGGER [updComments]
GO

Once we've ensured that the trigger, if it already exists, has been deleted, we can go ahead and create the trigger. Use the CREATE TRIGGER keyword followed by your name for the trigger. With CREATE TRIGGER you need to specify the trigger's name along with what table it operates on and for what database operation(s):

-- Create the trigger
CREATE TRIGGER updComments

--indicate which table the trigger is to be executed on
ON tstComments

--indicate whether it is an UPDATE, INSERT or DELETE Trigger
FOR UPDATE
AS

Now for the body of the trigger! Since we will be sending an email, we will need a variable to hold the body of the email (along with some other variables).

One thing to keep in mind is that a trigger only fires once per INSERT, UPDATE, or DELETE statement. If we want to process all of the records that were updated in a batch UPDATE statement, we'd need to use a CURSOR here. For this example, let's just assume that we only want to send off an email if exactly one record is updated. Therefore, our trigger won't send notifications if batch UPDATE statements are issued. In the trigger, the inserted table contains the record(s) that were just updated. Therefore, we can check this table to see how many records were updated.

-- Make sure only one record has been updated
-- (If more than one record has been updated, do nothing...)
IF (SELECT COUNT(*) FROM inserted) = 1
 BEGIN
   --holds the CommentID so we know which comment was updated
   declare @CommentID varchar(10)
   
   --holds the body of the email
   declare @body varchar(3000) 
   
   --holds the old comment which has been changed
   declare @oldcomment varchar(1000)
   
   --holds the new comment
	declare @newcomment varchar(1000)

We now need to assign values to the variables from the row that was just updated. The deleted table is a special table that holds the contents of the row that was updated right before it was updated. So it has the pre-updated values. We want to take these original values and store them into our @CommentID and @oldcomment variables:

   SELECT @CommentID = CommentID,
          @oldcomment = d.commentText
   FROM deleted d

Then we want to assign values to the variables from the row after it was updated. To access those valued we can use the inserted table:

   SELECT @newcomment = commentText
   FROM inserted

Set the body of the email by concatinating the strings and the variables. Notice the placement of the single quotes and carriage returns which allows for formatting in the email body:

   SET @body =
'CommentID ' + @CommentID + ' has been updated
Old Comment:' + @oldcomment + '
New Comment: ' + @newcomment

Finally, send the email using the xp_sendmail extended stored procedure. Since the procedure is in the master database and we are in pubs (or whatever database you may be adding this trigger to), we need to specify which database the xp_sendmail stored procedure is in. Moreover, in order to use this extended stored procedure you must have SQL Mail set up. See How to Configure SQL Mail for more information. Lastly, you must grant EXECUTE permissions for the xp_sendmail procedure in the master database. Assuming you're fulfilled all of these steps, the following statements will actually send the email to a specified account.

   --xp_sendmail is the extended sproc used to send the mail
   EXEC master..xp_sendmail 
            @recipients = 'you@example.com',
            @subject = 'Comments have been updated',
      	    @message = @body

 END  -- This ends the IF statement that ensures 
      -- only one record has been updated
GO

Testing the Trigger
After you have created the table, inserted the row and created the trigger, run this UPDATE statement to test out the trigger's functionality.

UPDATE tstComments SET
    commentText = 'this is the updated comment'
WHERE CommentID = 1

If everything is configured correctly, you should receive the following email:

CommentID 1 has been updated
Old Comment:this is the original comment
New Comment: this is the updated comment
You can explore the SQL Server Books Online to find many other useful parameters to the xp_sendmail procedure as well as detailed descriptions of other types of triggers. Now that you've seen how easy triggers and SQL Mail are, you will no doubt find lots of uses for them!

Happy Programming!

  • By Wade Wilbur


    Attachments:

  • Download the complete SQL script

    Return to user tips...


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article