使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM