如何使用C#监听SQL Server数据库



        新建一个SQL CLR数据库项目,来对数据库的变化进行监听,如:当有数据发生变化(增删改), SQL CLR数据库项目就会获得通知,此时我们在开启一个Socket,将数据库变化的消息发送到IIS服务器,IIS服务器然后再发布出数据库已发送变化的消息,此时连接到服务器的客户端就会收到通知,就会根据服务器发来的表名,去决定是否需要重新获取数据,已达到客户端的数据是实时数据的效果:

第一步:

第二:

using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
using System.Web.Services;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Runtime.Remoting.Contexts;

public partial class Triggers
{
    // 为目标输入现有表或视图并取消对特性行的注释
    [Microsoft.SqlServer.Server.SqlTrigger(Name = "Trigger1", Target = "Users", Event = "AFTER INSERT, UPDATE")]
    public static void Trigger1()
    {
        SqlContext.Pipe.Send("hehuajun");
        List<Socket> socketPool = new List<Socket>();
        bool firstTime = true;
        SqlTriggerContext triggContext = SqlContext.TriggerContext;
        SqlParameter userName = new SqlParameter("@username", System.Data.SqlDbType.NVarChar);

        if (triggContext.TriggerAction == TriggerAction.Insert)
        {
            using (SqlConnection conn = new SqlConnection("context connection=true"))
            {
                conn.Open();
                SqlCommand sqlComm = new SqlCommand();
                SqlPipe sqlP = SqlContext.Pipe;
                sqlComm.Connection = conn;
                sqlComm.CommandText = "SELECT UserName from INSERTED";
                userName.Value = sqlComm.ExecuteScalar().ToString();
                sqlComm.CommandText = "INSERT UsersAudit(UserName) VALUES('" + userName + "')";
                sqlP.Send(sqlComm.CommandText);
                sqlP.ExecuteAndSend(sqlComm);
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.10.11"), 4502); //填写自己电脑的IP或者其他电脑的IP,如果是其他电脑IP的话需将ConsoleApplication_socketServer工程放在对应的电脑上。  
                SqlServerProjectDemo.TableNotifyProtocol p = new SqlServerProjectDemo.TableNotifyProtocol();
                p.TableName = "Users";
                p.OperatorOnTable = "Update";
                socket.Connect(ipep);
                socket.Send(p.TableNotifyProtocolToBytes());
                socket.Close();
            }
        }
    }

    //static Socket serverSocket;
    // static Socket clientSocket;
    // static Thread thread;
    //public static void StartSocket()
    //{
    //    IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 4530);
    //    serverSocket = new Socket(ipep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    //    serverSocket.Bind(ipep);
    //    serverSocket.Listen(10);
    //    while (true)
    //    {
    //        Socket s = serverSocket.Accept();
    //        socketPool.Add(s);
    //        // clientSocket = s;
    //       // thread = new Thread(new ThreadStart(doWork));
    //        thread = new Thread(new ThreadStart(() =>
    //        {
    //            doWork(s, ASCIIEncoding.ASCII.GetBytes("1"));
    //        }));
    //        thread.Start();
    //    }
    //}

    //public static void doWork(Socket s, byte[] buffer)
    //{
    //    //  Socket s = clientSocket;//客户端信息 
    //    IPEndPoint ipEndPoint = (IPEndPoint)s.RemoteEndPoint;
    //    String address = ipEndPoint.Address.ToString();
    //    String port = ipEndPoint.Port.ToString();
    //    Console.WriteLine(address + ":" + port + " 连接过来了");
    //    Byte[] inBuffer = new Byte[1024];
    //    Byte[] outBuffer = new Byte[1024];
    //    String inBufferStr;
    //    String outBufferStr;
    //    try
    //    {
    //        while (true)
    //        {
    //            // s.Receive(inBuffer, 1024, SocketFlags.None);//如果接收的消息为空 阻塞 当前循环  
    //            // inBufferStr = Encoding.ASCII.GetString(inBuffer);
    //            // Console.WriteLine(address + ":" + port + "说:");
    //            // Console.WriteLine(inBufferStr);
    //             outBufferStr = Console.ReadLine();
    //            // //outBufferStr = p.TableNotifyProtocolToBytes();
    //            // //outBuffer = Encoding.ASCII.GetBytes(outBufferStr);
    //            // outBuffer = p.TableNotifyProtocolToBytes();
    //            s.Send(buffer, buffer.Length, SocketFlags.None);
    //        }
    //    }
    //    catch
    //    {
    //        Console.WriteLine("客户端已关闭!");
    //    }
    //}

    public bool IsEMailAddress(string s)
    {
        return Regex.IsMatch(s, "^([\\w-]+\\.)*?[\\w-]+@[\\w-]+\\.([\\w-]+\\.)*?[\\w]+$");
    }
}
第三步:为了能使用Socket,需要为程序集签名:


 
第四步:
在数据库中执行:
USE master;

CREATE ASYMMETRIC KEY SQLCLRTestKey1
    FROM EXECUTABLE FILE = 'C:\SqlServerProjectDemo.dll'
    CREATE LOGIN SQLCLRTestLogin FROM ASYMMETRIC KEY SQLCLRTestKey  
    GRANT EXTERNAL ACCESS ASSEMBLY TO SQLCLRTestLogin; 

 GO 

 
注意:最好不要直接使用debug目录,可以将你的项目生成的dll拷贝到另外的地方。如:C:\SqlServerProjectDemo.dll
F5启动部署:
成功后:
在数据库中执行
insert into Users(UserName,Pass) values('admin','admin')

Update Users set UserName='哈哈哈' where UserName='admin'
然后在你的Socket端的服务器上就会收到 你发送过去的数据。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SqlServerProjectDemo
{
    public struct TableNotifyProtocol
    {
        public string TableName;
        public string OperatorOnTable;
        public byte[] TableNotifyProtocolToBytes()
        {
            string s = "TableName=" + TableName + "|" + "OperatorOnTable=" + OperatorOnTable+"|";
            byte[] bTableName = ASCIIEncoding.ASCII.GetBytes(TableName);
            byte[] bOperatorOnTable = ASCIIEncoding.ASCII.GetBytes(OperatorOnTable);
            //byte[] buffer = new byte[bTableName.Length + bOperatorOnTable.Length];
            //ASCIIEncoding.ASCII.GetBytes(TableName, 0, bTableName.Length, buffer, 0);
            //ASCIIEncoding.ASCII.GetBytes(OperatorOnTable, 0, bOperatorOnTable.Length, buffer, bTableName.Length);
            byte[] buffer = ASCIIEncoding.ASCII.GetBytes(s);
            return buffer;
        }

        public TableNotifyProtocol GetModel(byte[] buffer)
        {
            string s = ASCIIEncoding.ASCII.GetString(buffer);
            TableNotifyProtocol model = new TableNotifyProtocol();
            model.OperatorOnTable = GetString(s, "OperatorOnTable");
            model.TableName = GetString(s, "TableName");
            return model;
        }

        private string GetString(string s,string key)
        {
            string tmp = s.Substring(s.IndexOf(key) + key.Length + 1);
            string v=tmp.Substring(0,tmp.IndexOf("|"));
            return v;
        }
    }
}

 
以下是使用C#代码监听SQL Server数据库的示例: ```csharp using System; using System.Data.SqlClient; class Program { static void Main() { string connectionString = "Data Source=(local);Initial Catalog=YourDatabase;Integrated Security=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); SqlDependency.Start(connectionString); Console.WriteLine("Listening to database changes..."); using (SqlCommand command = new SqlCommand("SELECT * FROM YourTable", connection)) { SqlDependency dependency = new SqlDependency(command); dependency.OnChange += new OnChangeEventHandler(OnNotificationChange); // Start the command execution using (SqlDataReader reader = command.ExecuteReader()) { // Process the data } } } } private static void OnNotificationChange(object sender, SqlNotificationEventArgs e) { Console.WriteLine("Database changed!"); // Handle the database change event } } ``` 在上面的示例中,我们创建一个 `SqlConnection` 实例并使用 `SqlDependency.Start()` 方法启动侦听器。然后,我们创建一个 `SqlCommand` 实例并将其传递给 `SqlDependency` 构造函数,然后订阅 `SqlDependency.OnChange` 事件,该事件将在数据库更改时触发。在事件处理程序中,您可以处理数据库更改事件。 请注意,为了使侦听器正常工作,需要进行以下配置: 1. SQL Server 服务必须启用 Service Broker。 2. 数据库必须启用 Service Broker 并启用对该数据库的通知。 3. 授予使用数据库的用户 RECEIVE 权限。 希望能对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疋疋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值