Click here to Skip to main content
Click here to Skip to main content

Using Query Notifications in .NET 2.0 to handle ad-hoc data refreshes

By , 1 Feb 2006
 

Introduction

Query Notification in SQL Server 2005 solves the problem of having to maintain a polling database to get the updated data. The new notification service of SQL Server 2005 can perform this amazing task of notifying a .NET code when any DML operations are performed to a specified table. The notification cycle starts from the .NET 2.0 application through the object named SqlDependency in the System.Data.SqlClient namespace, the object just takes the SQLCommand object which has the query.

SqlCommand cmd = new SqlCommand("SELECT ID, Name, " + 
   "Address FROM dbo.employee", SQLConnectionObject));
SqlDependency depend = new SqlDependency(cmd);

The dependency has to be started using:

SqlDependency.Start(connstring);
//It takes the connection string as a parameter.

Now, the question is how and who would get notified?

The answers lies in the SQLDependency instance you make. You can delegate an event handler on the OnChange event of the SqlDependency object.

SqlDependency depend = new SqlDependency(cmd);
SqlDependency.Start(connstring);
depend.OnChange += new OnChangeEventHandler(MyOnChanged);

So when the notification arrives, it goes to the specified handler.

Preparing SQL Server 2005 for Notifications

  1. Install the Notification Service

    You will have to install the SQL Server Notification Service from the SQL Server 2005 installation package. If it is already installed, you will surely see a ‘Notification Services’ folder in the SQL Server Management Studio.

  2. Enable the .NET CLR

    You will have to enable the .NET CLR for SQL Server 2005, because the service broker uses it.

    To enable .NET CLR, execute this command:

    EXEC sp_configure 'show advanced options' , '1';
    go
    reconfigure;
    go
    EXEC sp_configure 'clr enabled' , '1'
    go
    reconfigure;
    go
  3. Enable Broker

    Query Notifications use the Service Broker SERVICEs. A SERVICE in this case is a destination for asynchronous messages; the messages can be required to follow a specific set of rules known as a CONTRACT. A Service Broker SERVICE is always associated with a QUEUE that is the physical message destination.

    The broker has to be enabled for each database using the following statement:

    ALTER DATABASE databasename SET ENABLE_BROKER
  4. Grant Permissions

    Grant permission to the user using the following statement:

    GRANT SUBSCRIBE QUERY NOTIFICATIONS TO username

About Notifications

The created notification is always executed once. So when a notification arrives, its job is done, and to continue receiving notification, you will have to recreate the SqlDependency on the handler.

The best usage of the query notification is in the case of caching. You don’t have to poll the database from time to time to find out any data changes. You can invalidate the cache in the handler and get the data table again, and along with that re-create the SqlDependency with a fresh notification.

Please note, since the SQL Server 2005 Express does not support the notification service, you will not be able to perform Query Notification in SQL Server 2005 Express.

Links

For more information, you can go through this article:

This article covers a custom notification query using SqlNotificationRequest, Service Broker, and Queues.

Sample

The following sample code snippet uses the SQL Server notification feature:

using System.Data.SqlClient;
public void button1_Click(object sender, EventArgs e)
{
    string connstring = @"Data Source=SQLServer2005;" + 
       @"Initial Catalog=TestDB;Persist Security Info" + 
       @"=True;User ID=username;Password=password;" + 
       @"Pooling=True;Min Pool Size=5;Max Pool Size=100;" + 
       @"Asynchronous Processing=True;" + 
       @"MultipleActiveResultSets=True;Connect Timeout=15";
    List<string> list = new List<string>();
    using (SqlConnection conn = new SqlConnection(connstring))
        using (SqlCommand cmd = new SqlCommand("SELECT" + 
               " SELECT ID, Name, Address" + 
               " FROM dbo.employee", conn))
        {
            try
            {
                SqlDependency depend = new SqlDependency(cmd);
                SqlDependency.Start(connstring);
                depend.OnChange += new 
                  OnChangeEventHandler(MyOnChanged);
                conn.Open();
                SqlDataReader rdr = cmd.ExecuteReader();
                //perform any operation here
                while (rdr.Read())
                    list.Add(rdr[0].ToString());
                rdr.Close();
            }
            catch (Exception ee)
            {
                    string msg = ee.Message;
            }
        }
}

static void MyOnChanged(object caller, SqlNotificationEventArgs e)
{
    //to test place a break point here 
    //and change any data in the specified table
    string msg = "Notified";
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

rajiv404
India India
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralWorks (sort-of) in SQL Server Express 2005 (aka SSE)memberwwalseth7 Dec '06 - 14:57 
I have this working in SQL Server 2005 Express.
 
It works for a while, (the Cache is cleaned out and re-populated when I change the table), but after a minute or two, my .NET app is out of date... UGH!
 
Check-out Jeff Prosise's BLOG. Creating an ENDPOINT for the Service Broker enables appears to enable it in SQL Server 2005 Express
 
http://www.wintellect.com/Weblogs/CommentView,guid,fe9a1322-6375-471c-9384-5070498d108e.aspx[^]
 
USE master;
GO
 
CREATE ENDPOINT BrokerEndpoint
STATE = STARTED
AS TCP ( LISTENER_PORT = 4037 )
FOR SERVICE_BROKER ( AUTHENTICATION = WINDOWS );
GO
 

 

 
You can always tell a Texan, but you can't tell him anything
Generalhelp pleasemembercsmba15 Mar '06 - 13:10 
I did a small sample...
It works great at first, I manualy change the DB and I get a notification...
BUT, if I don't change anyting in my application for 10 minuts, and then change the DB, I do not get a notification! how can I debug this? what is the reason?
GeneralRe: help pleasememberrajiv40415 Mar '06 - 19:39 
Hello,
 
I am not very clear about your problem.. but i guess u got a notification first time you changed the table and you didnt get the notification second time.. this is because notification is just done once and after every single notification the notification expires.. u will have to recreate the notification using the sqldependency every time u get the first notification.
 

 


 
Bye,
Rajiv
GeneralRe: help pleasemembercsmba15 Mar '06 - 20:13 
nice try, but it will not be that simple...
 
I did my home work. it is not a trivial mistake like that.. well, it might be, but that this one. to be more detailed:
I can repeat this action many times:
1. change data in DB
2. watch log line "call back function called, reloading" being written
3. go back to step 1.
 
It works great! BUT, if I walk away from the computer for 6-10 minuts without repeating step 1-3, then after 10 minuts I do step 1 and...
nothing happens!
 
Where the H%^% is the notification? what happens to it?
GeneralRe: help pleasememberCoderQue13 Aug '06 - 7:19 
Looks like there is a timeout that you need to define:
 
e.g.
 
SqlDependency depend = new SqlDependency(cmd,
null,
SqlNotificationAuthType.None,
SqlNotificationEncryptionType.None,
SqlNotificationTransports.Tcp,
10000);
 
10000 in this case is 10000 seconds.
 

 
Coder Que

GeneralRe: help pleasemembergrumpy-wan6 May '07 - 16:12 
The suggestion above might work, but not necessarily for the right reasons. There's also an issue with ADO.NET referred to (with a fix) at
http://support.microsoft.com/Default.aspx?kbid=913364
 
This refers specifically to notifications which seem to get lost (or ignored, as you can see them firing at the SQL end) after waiting for a few minutes after first setting the dependency up.
GeneralRe: help pleasemembershimesrle19 May '07 - 11:41 
Dear grumpy-wan.
 
Many,many,many thanks.
 
I have this problem for more than a year. I have tried everything that I can to find out why after 5 minutes of inactivity in database my sqldependency stops. Countless hours of searching on internet produce nothing.
The only thing that I found to work is to set dependency timeout to no more than 3 min.Smile | :)
 
Once again thanks.
AnswerSome mistakesmemberMarcel 876549 Feb '06 - 2:53 
Hi, there are some mistakes
 
1. Query Notifications has nothing common with SQL Server Notification Services
- you dont need install Notification Services
- it should also work on SQL Server Express
 
2. Query Notifications dont need CLR support enabled
 
The base technologies are
- Service Broker (and must be enabled), check also the SQL Server Surface Area Configuration - Tool
 
- Change detection mechanism for indexed views
- thats why be care full with your select statements
- no Select * , you need to specify every column
- no Select Name From customer you need Select Name From dbo.customer
 
An article (in german) is here: Yukon is calling[^]
 
There are also two articles about Service Broker
 
Marcel
 
-------------------------
www.gnoth.net
 

GeneralRe: Some mistakesmemberrajiv40415 Mar '06 - 19:42 
Thanks Marcel for correcting the mistakes.. though i havent checked it but it would certainly help the readers.. well others can go through the msdn link i have provided in the article for more clarifications because i did as it was specified by this article..
 
Rajiv

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 2 Feb 2006
Article Copyright 2006 by rajiv404
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid