1. 程式人生 > >使用SqlDependency實現程式對於資料庫中表資料變化的監視

使用SqlDependency實現程式對於資料庫中表資料變化的監視

好久沒有寫部落格了,感覺有點生疏了。

今天和大家分享一個數據庫變化自動通知客戶端的技巧,現在還是侷限在sqlServer上的使用,在文章最後附上原始碼

今天的主角就是SqlDependency--實現資料庫中對於某一張表的監視,好了。廢話不多說了,開始搞,今天我新建了個簡單的WPF專案如下:

1、首先需要對資料庫的設定:

 **  1、設定某個資料庫代理的回滾 
 *      ALTER DATABASE [test] SET NEW_BROKER WITH ROLLBACK IMMEDIATE; 
 *  2、設定某個資料庫的代理 
 *      ALTER DATABASE [test] SET ENABLE_BROKER; 
 
* 3、查詢某個資料庫是否已經啟動了代理 * SELECT name,is_broker_enabled FROM sys.databases WHERE name = 'yaozheng' * is_broker_enabled 為0表示未啟動代理 1表示已啟動代理

2、開始c#程式碼 ,初始化方法中啟動監聽器

        /// <summary>
        /// 初始化
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            // 啟動偵聽器來接收來自通過連線字串指定的 SQL Server 例項的依賴項更改通知。
            SqlDependency.Start(_connStr);
            SelectData();
        }

3、寫一個簡單的資料庫查詢SelectData,重點就是

                    SqlDependency dependency = new SqlDependency(command);
                    // 事件註冊,這是核心
                    dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange);

詳細如下:

        /// <summary>
        /// 資料庫查詢操作
        /// </summary>
private static void SelectData() { using (SqlConnection connection = new SqlConnection(_connStr)) { //依賴是基於某一張表的,而且查詢語句只能是簡單查詢語句,不能帶top或*,同時必須指定所有者,即類似[dbo].[] string cmdText = "SELECT [ID],[Name],[Age] from dbo.Test_Table where [Age] = 1"; using (SqlCommand command = new SqlCommand(cmdText, connection)) { command.CommandType = CommandType.Text; connection.Open(); SqlDependency dependency = new SqlDependency(command); // 事件註冊,這是核心 dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange); SqlDataReader sdr = command.ExecuteReader(); Console.WriteLine(); while (sdr.Read()) { Console.WriteLine("Id:{0}\\Name:{1}\\Age:{2}", sdr["ID"].ToString(), sdr["Name"].ToString(), sdr["Age"].ToString()); } sdr.Close(); } } }
4、實現Dependency_OnChange方法,在資料庫中資料發生變化時,重新獲取
        /// <summary>
        /// 具體事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            // 只有資料發生變化時,才重新獲取資料 
            if (e.Type == SqlNotificationType.Change)
            {
                SelectData();
            }
        }

 5、WPF還有一個資源的自動釋放,關閉監聽

       
        /// <summary>
        /// 注意資源的釋放 關閉監聽
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closed(object sender, EventArgs e)
        {
            SqlDependency.Stop(_connStr);
        }

 

以上操作就可以實現資料庫資料變化時自動觸發 SelectData() 方法。

以下重點說下注意事項,是我在實際使用過程中踩過的坑,希望大家可以避免:

* 1、應用程式開始或者結束時,必須相應的開始或者停止對SQL Server的監控。
* 2、只有SQL語句中需要查詢的欄位才會被監控,沒有查詢的資料發生變化時,並不會觸發dependency_OnChange事件。
* 3、查詢語句只能是簡單查詢語句,不能帶top,不能使用*,不能使用函式包括聚合函式,包括where子查詢
* 4、不能使用外連線、自連線、不能使用臨時表、不能用變數、不能用試圖、不能跨表、表名前必須加型別dbo的字首
* 5、待查詢的欄位的資料也不能太複雜。測試時,有個欄位儲存Json格式的資料。如果將這個欄位也寫入到SQL語句中,則不會被監控到。
* 6、OnChange只能提供一次通知,如果需要重新發起,需要重新新增事件

 最後附上原始碼

原始碼:https://github.com/YaoHigh/SqlDependencyTest