C#--SqlDependency监控数据库表的变化

 SqlDependency提供了这样一种能力:当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的。

 

/*
 * 注意事项:

1.修改Database设置
alter database set enable_broker with rollback immediate;

2.SQL的查询语法中不能使用 [*] 的方式
[错误的:] select * From [dbo].[alarm_table]

[正确的] select sn,address,create_time From [dbo].[alarm_table]
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SqlDependency_Test
{
    public partial class MainForm : Form
    {
        /* 确认DB有执行 [alter database <dbname> set enable_broker with rollback immediate;] */
        SqlConnection connection = new SqlConnection();
        private static string ConnectionString;

        public MainForm()//构造
        {
            InitializeComponent();
        }

        /* 启动SQL监控 */
        private void btn_Start_Click(object sender, EventArgs e)
        {
            try
            {
                ConnectionString = "Data Source=" + txt_dbSource.Text + ";Initial Catalog=" + txt_dbDatabase.Text + ";User ID=" + txt_dbUser.Text + ";Password=" + txt_dbPassword.Text;
                SqlDependency.Start(ConnectionString);//调用SqlDependency.Start(String strConnectionString)方法,在应用程序端启用依赖监听器。
                SqlDependencyWatch();
                RefreshTable();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        /* 关闭SQL监控 */
        private void btn_Stop_Click(object sender, EventArgs e)
        {
            SqlDependency.Stop(ConnectionString);
        }

        /* 关闭SQL监控 */
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            SqlDependency.Stop(ConnectionString);
        }

        /* 建立SQL监控 */
        private void SqlDependencyWatch()
        {
            string sSQL = "SELECT [ID],[Name],[Sex],[Birth],[Password],[Insert_Time] FROM [dbo].[T_User]";

            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                using (SqlCommand command = new SqlCommand(sSQL, connection))
                {
                    command.CommandType = CommandType.Text;
                    connection.Open();
                    SqlDependency dependency = new SqlDependency(command);
                    dependency.OnChange += new OnChangeEventHandler(SQLTableOnChange);
                    SqlDataReader sdr = command.ExecuteReader();
                }
            }
        }

        /* 资料表修改触发Event事件处理 */
        void SQLTableOnChange(object sender, SqlNotificationEventArgs e)
        {
            SqlDependencyWatch();
            RefreshTable();
        }

        /* 重新更新DataGridView显示资料 */
        private void RefreshTable()
        {
            string sSQL = "SELECT TOP 100 [ID],[Name],[Sex],[Birth],[Password],[Insert_Time] FROM [dbo].[T_User]";

            DataTable datatable = new DataTable();
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                connection.Open();
                using (SqlCommand cmd = new SqlCommand(sSQL, connection))
                {
                    using (SqlDataAdapter dr = new SqlDataAdapter(sSQL, connection))
                    {
                        dr.Fill(datatable);
                        this.Invoke((EventHandler)(delegate { dgv_Show.DataSource = datatable; }));
                    }
                }
            }
        }
    }
}

 

 

在添加完以上代码运行后会出现“未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker”:

 

 查看数据库监听服务是否开启:

SELECT is_broker_enabled FROM sys.databases WHERE name = 'DB_MyDB';

 

查询结果:is_broker_enabled de 结果是  0,代表数据库没有启动 Service Broker

只有数据库启用监听服务,才支持SqlDependency特性。

 

解决办法:注:两句同时执行,单独执行显示:正在回滚不合法事务。估计回滚已完成: 100%。

USE DB_MyDB  
GO
ALTER DATABASE DB_MyDB SET NEW_BROKER WITH ROLLBACK IMMEDIATE; 

ALTER DATABASE DB_MyDB  SET ENABLE_BROKER; 

 

  再次查询is_broker_enabled状态,状态为1,数据库没有启动 Service Broker成功。

 

 

参考:https://www.haolizi.net/example/view_16216.html

posted @ 2020-04-15 09:43  让挑战成为习惯  阅读(1609)  评论(0编辑  收藏  举报