設置具體數據庫啓動Service Broker服務,如下圖:
我這裏試例數據庫的名字爲“ghj_Demo”,修改 Broker Enabled 屬性爲 true。
你也可以用SQL 語句來修改,修改的SQL語句如下:
ALTER DATABASE ghj_Demo SET ENABLE_BROKER
確保你將使用的數據庫帳戶具有必需的權限
你在後面連接這個數據庫的帳戶,要確保對這個數據庫具有 SUBSCRIBE、 QUERY 、NOTIFICATIONS 的權限。
下面就是一個簡單的代碼例子,來演示查詢通知。這裏用到一個我自己建立的表:
這個表結構如下:
CREATE TABLE [dbo].[User]( [UserName] [nvarchar](20) NOT NULL, [Email] [nvarchar](50) NULL ) ON [PRIMARY] GO
演示的控制檯代碼如下:
using System; using System.Data; using System.Data.SqlClient; namespace Demo { class Program { public static string connectionstring = "Data Source=.;Initial Catalog=ghj_Demo;Integrated Security=True"; public void DoDependency() { using (SqlConnection conn = new SqlConnection(connectionstring)) { // sql is a local procedure that returns // a paramaterized SQL string. You might want // to use a stored procedure in your application. string sql = "select [UserName] ,[Email] from dbo.[User]"; SqlCommand cmd = new SqlCommand(sql, conn); // Ensure the command object does not have a notification object. cmd.Notification = null; //Notification specific code SqlDependency dep = new SqlDependency(cmd); dep.OnChange += new OnChangeEventHandler(TestEvent); conn.Open(); SqlDataReader r = cmd.ExecuteReader(); //Read the data here and close the reader r.Close(); conn.Close(); Console.WriteLine("DataReader Read..."); } } void TestEvent(Object o, SqlNotificationEventArgs args) { // 注意: // 如果Server端在很短的時間內發生了大量的改動(比如用了一個循環Update了好多行), // OnChanged必須能迅速處理事件,否則它只會被觸發一次。這個不是缺陷, // 因爲一般OnChanged事件處理函數內都要執行類似刷新緩存的操作,它只觸發一次, // 不會影響程序邏輯,卻能提高程序性能。 Console.WriteLine("======================"); Console.WriteLine("Event Recd"); Console.WriteLine("Info:" + args.Info); Console.WriteLine("Source:" + args.Source); Console.WriteLine("Type:" + args.Type); } static void Main(string[] args) { // In order to use the callback feature of the // SqlDependency, the application must have // the SqlClientPermission permission. try { SqlClientPermission perm = new SqlClientPermission(
System.Security.Permissions.PermissionState.Unrestricted); perm.Demand(); } catch { throw new ApplicationException("No permission"); } try { SqlDependency.Stop(connectionstring); //Start the listener infrastructure on the client SqlDependency.Start(connectionstring); Program q = new Program(); q.DoDependency(); Console.WriteLine("Wait for Notification Event..."); Console.Read(); } finally { //Optional step to clean up dependency else it will fallback to automatic cleanup SqlDependency.Stop(connectionstring); } } } }
一些注意事項:摘自MSDN文檔
使用查詢通知功能的應用程序需要考慮下列特殊注意事項。
注意事項 |
說明 |
SQL Server 的服務帳戶 |
對於使用本地系統帳戶作爲服務帳戶的 SQL Server 實例,應用程序不會從其接收通知。 |
接收通知 |
無法在運行 Windows 95 或 Windows 98 的計算機上接收通知。 |
查詢通知和事務 |
如果在某一事務內進行了多項影響具有已註冊通知請求的一組數據的修改,則僅會發送單個通知事件。 |
快速更新和查詢通知 |
使用查詢通知的應用程序必須考慮到立即出現通知的情況。服務器上的數據更改時,通知消息將發送到相應的服務中介程序隊列。 應用程序需要註冊才能接收其他通知。 因此,如果多個應用程序快速更新某個數據集,應用程序在緩存刷新後,立即可以接收通知,檢索數據,然後獲取另一個更新通知。 編寫使用查詢通知的應用程序時必須考慮到此情況。 如果應用程序使用不斷更新的數據,則可能更適合使用另一種數據緩存策略。 |
設置選項設置 |
在通知請求下執行 SELECT 語句時,提交請求的連接必須設置以下選項: · ANSI_NULLS ON · ANSI_PADDING ON · ANSI_WARNINGS ON · CONCAT_NULL_YIELDS_NULL ON · QUOTED_IDENTIFIER ON · NUMERIC_ROUNDABORT OFF · ARITHABORT ON |
編寫通知查詢語句的約束
您可以爲 SELECT 和 EXECUTE 語句設置通知。 使用 EXECUTE 語句時,SQL Server 會爲執行的命令而不是 EXECUTE 語句本身註冊通知。 該命令必須滿足 SELECT 語句的要求和限制。 當註冊通知的命令包含多個語句時,數據庫引擎會爲批處理中的每個語句創建一個通知。
對滿足以下要求的 SELECT 語句支持查詢通知:
-
SELECT 語句中的提取的列必須顯式聲明,且表名稱必須用由兩部分組成的名稱進行限定。 請注意,這意味着語句中引用的所有表都必須位於同一個數據庫中。
-
語句不能使用星號 (*) 或 table_name.* 語法來指定列。
-
語句不能使用未命名的列或重複的列名稱。
-
語句必須引用一個基表。
-
SELECT 語句中的提取的列不能包含聚合表達式,除非該語句使用 GROUP BY 表達式。 在提供 GROUP BY 表達式的情況下,選擇列表可以包含聚合函數 COUNT_BIG() 或 SUM()。 不過,不能爲可以爲 null 的列指定 SUM()。 語句不能指定 HAVING、CUBE 或 ROLLUP。
-
SELECT 語句中的提取的列用作簡單表達式時不能出現多次。
-
語句不能包含 PIVOT 或 UNPIVOT 運算符。
-
語句不能包含 INTERSECT 或 EXCEPT 運算符。
-
語句不能引用視圖。
-
語句不能包含以下任一項: DISTINCT、COMPUTE、COMPUTE BY 或 INTO。
-
語句不能引用服務器全局變量 (@@variable_name)。
-
語句不能引用派生表、臨時表或表變量。
-
語句不能引用其他數據庫或服務器中的表或視圖。
-
語句不能包含子查詢、外部聯接或自聯接。
-
語句不能引用大型對象類型: text、ntext 和 image。
-
語句不能使用 CONTAINS 或 FREETEXT 全文謂詞。
-
語句不能使用行集合函數,包括 OPENQUERY 和 OPENROWSET。
-
語句不能使用以下任一集合函數: AVG、COUNT(*)、MAX、MIN、STDEV、STDEVP、VAR 或 VARP。
-
語句不能使用任何不確定性函數,包括排名和開窗函數。
-
語句不能包含用戶定義的聚合。
-
語句不能引用系統表或視圖,包括目錄視圖和動態管理視圖。
-
語句不能包含 FOR BROWSE 信息。
-
語句不能引用隊列。
-
語句不能包含無法更改或無法返回結果的條件語句(例如 WHERE 1=0)。
sunmast 對查詢通知的注意事情也有很多有價值的整理:
使用SQL Server 2005 Query Notification的幾個注意事項
http://blog.joycode.com/sunmast/archive/2006/08/11/sql_2005_query_notification_comments_79814.aspx
參考資料:
剖析SQL Server 2005查詢通知之基礎
http://www.allwiki.com/wiki/%E5%89%96%E6%9E%90SQL_Server_2005%E6%9F%A5%E8%AF%A2%E9%80%9A%E7%9F%A5%E4%B9%8B%E5%9F%BA%E7%A1%80
Using SqlDependency for data change events
http://www.codeproject.com/KB/database/chatter.aspx
SQL Server 2005 Service Broker 初探
http://msdn.microsoft.com/zh-cn/library/ms345108.aspx
SQL Server 2005數據庫開發詳解
http://book.csdn.net/bookfiles/24/10024713.shtml
C# Windows 應用程序中實現 SQL Server 2005 查詢通知
http://support.microsoft.com/kb/555893/zh-cn
SqlDependency changes for RTM [Sushil Chordia]
http://blogs.msdn.com/dataaccess/archive/2005/09/27/474447.aspx
.NET 2.0 SqlDependency快速上手指南
http://www.cnblogs.com/Xrinehart/archive/2006/07/27/461106.html
在 Windows 應用程序中使用 SqlDependency
http://msdn.microsoft.com/zh-cn/library/a52dhwx7(VS.80).aspx
Using SqlDependency in an ASP.NET Application
http://msdn.microsoft.com/en-us/library/9dz445ks(VS.80).aspx
Minimum Database Permissions Required for SqlDependency
http://www.codeproject.com/KB/database/SqlDependencyPermissions.aspx
使用SQL Server 2005 Query Notification的幾個注意事項
http://blog.joycode.com/sunmast/archive/2006/08/11/sql_2005_query_notification_comments_79814.aspx