zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    页面的加载过程
    free 命令
    linux chmod命令(转)
    less 命令(转)
    cat 命令(转)
    cp 命令(转)
    mv命令(转)
    rm 命令(转)
    mkdir命令
    Docker网络基础
  • 原文地址:https://www.cnblogs.com/highest/p/10117132.html
Copyright © 2011-2022 走看看