zoukankan      html  css  js  c++  java
  • 使用SqlDependency监听MSSQL数据库表变化通知

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

    首先要对数据库进行配置,配置命令如下:

    1.启用Service Broker并查看是否启用成功,is_broker_enabled为1则表明启用成功:

    ALTER DATABASE SqlDepTest SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE SqlDepTest SET ENABLE_BROKER;
    SELECT is_broker_enabled FROM sys.databases WHERE name = 'SqlDepTest'

    2.开启帐号订阅权限,由于sa帐号不支持权限设置,所以需要建立单独的帐号。

    use master

    GRANT CREATE PROCEDURE TO sqldep
    GRANT CREATE QUEUE TO sqldep
    GRANT CREATE SERVICE TO sqldep

    use master
    GRANT SUBSCRIBE QUERY NOTIFICATIONS TO sqldep
    exec sp_helprotect NULL, sqldep

    C#示例代码如下:

    [csharp] view plain copy
     
      1. private const string SQL_CONNECTIONSETTINGS = "";  
      2.   
      3. static void Main(string[] args)  
      4. {  
      5.     //传入连接字符串,启动基于数据库的监听  
      6.     SqlDependency.Start(SQL_CONNECTIONSETTINGS);  
      7.     HandleMessage();  
      8.   
      9.     Console.Read();  
      10. }  
      11.   
      12. /// <summary>  
      13. /// 触发处理消息机制  
      14. /// </summary>  
      15. private static void HandleMessage()  
      16. {  
      17.     using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))  
      18.     {  
      19.         //依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]  
      20.         using (SqlCommand command = new SqlCommand("SELECT [MessageID],[Messages],[CreateTime] FROM [dbo].[Messages]", connection))  
      21.         {  
      22.             int messageID = 0;  
      23.             command.CommandType = CommandType.Text;  
      24.             connection.Open();  
      25.             command.Notification = null;  
      26.             SqlDependency dependency = new SqlDependency(command);  
      27.             dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange);  
      28.   
      29.             SqlDataReader sdr = command.ExecuteReader();  
      30.             while (sdr.Read())  
      31.             {  
      32.                 int.TryParse(sdr["MessageID"].ToString(), out messageID);  
      33.                 ProcessMessage(messageID);  
      34.                 Console.WriteLine("MessageID:{0} Messages:{1} CreateTime: {2}", sdr["MessageID"].ToString(), sdr["Messages"].ToString(), sdr["CreateTime"].ToString());  
      35.                 CompleteProcessMessage(messageID, 2);  
      36.             }  
      37.             sdr.Close();  
      38.         }  
      39.     }  
      40. }  
      41.   
      42. /// <summary>  
      43. /// SQL消息触发事件  
      44. /// </summary>  
      45. /// <param name="sender"></param>  
      46. /// <param name="e"></param>  
      47. private static void Dependency_OnChange(object sender, SqlNotificationEventArgs e)  
      48. {  
      49.     SqlDependency dependency = sender as SqlDependency;  
      50.     dependency.OnChange -= Dependency_OnChange;  
      51.     HandleMessage();  
      52. }  
      53.   
      54. /// <summary>  
      55. /// 处理消息  
      56. /// </summary>  
      57. /// <param name="messageID">消息编号</param>  
      58. private static void ProcessMessage(int messageID)  
      59. {  
      60.     using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))  
      61.     {  
      62.         string sql = string.Format(@"INSERT INTO [dbo].[MessagesComplete]  
      63.                        SELECT [MessageID],[Messages],1,[CreateTime],GETDATE()  
      64.                        FROM [dbo].[Messages] WHERE [MessageID] = {0}  
      65.                        DELETE FROM [dbo].[Messages] WHERE [MessageID] = {0}", messageID);  
      66.         using (SqlCommand command = new SqlCommand(sql, connection))  
      67.         {  
      68.             command.CommandType = CommandType.Text;  
      69.             connection.Open();  
      70.             command.ExecuteNonQuery();  
      71.             command.Dispose();  
      72.         }  
      73.     }  
      74. }  
      75. /// <summary>  
      76. /// 消息处理完成,更新消息处理状态  
      77. /// </summary>  
      78. /// <param name="messageID">消息编号</param>  
      79. /// <param name="status">状态:1.处理中,2.处理完成,-1.处理失败</param>  
      80. private static void CompleteProcessMessage(int messageID, int status)  
      81. {  
      82.     using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))  
      83.     {  
      84.         string sql = string.Format("UPDATE [dbo].[MessagesComplete] SET [Status] = {1} WHERE [MessageID] = {0}", messageID, status);  
      85.         using (SqlCommand command = new SqlCommand(sql, connection))  
      86.         {  
      87.             command.CommandType = CommandType.Text;  
      88.             connection.Open();  
      89.             command.ExecuteNonQuery();  
      90.             command.Dispose();  
      91.         }  
      92.     }  
      93. }  
  • 相关阅读:
    管理索引表:深入研究B树索引重建,合并,删除(理论篇3)
    关于ASP.NET中Membership进行权限管理不足的解决办法
    将VS2005中的.CS文件在网页中显示的方法
    在页面中直接设计TreeView的节点而不使用Web.Sitemap文件在运行时出错
    (转)动态管理ASP.NET DataGrid数据列
    在页面中直接设计TreeView的节点而不使用Web.Sitemap文件在运行时出错
    将VS2005中的.CS文件在网页中显示的方法
    三天没有更新我的BLOG
    三天没有更新我的BLOG
    (转)动态管理ASP.NET DataGrid数据列
  • 原文地址:https://www.cnblogs.com/lip-blog/p/7244544.html
Copyright © 2011-2022 走看看