查看新表单的SQL表的有效方法

时间:2015-04-17 21:19:46

标签: c# sql sql-server

我有一个将传入数据插入SQL表的推送服务,我需要创建一个应该监听此表的应用程序来查看新的传入数据。

有没有办法收听这个表而不必经常选择数据库进行新的更改?如果对这些数据没有用处,我只是在阅读之后删除该行,还是更好地定期清理?


UPDATE2


这是我的实际代码,它没有给我任何关于插入表的通知,我做错了什么?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;

namespace Navman_SPI_Service
{
    public partial class Service1 : ServiceBase
    {
        SqlConnection con = new SqlConnection();
        String passAvl = Properties.Settings.Default.AVLPass;
        String usuarioAvl = Properties.Settings.Default.AVLuser.ToString();
        String servidor = Properties.Settings.Default.Server.ToString();
        String DataB = Properties.Settings.Default.DB.ToString();
        String SQLuser = Properties.Settings.Default.DBuser.ToString();
        String SQLpass = Properties.Settings.Default.DBpassword.ToString();
        SqlCommand dependencyCommand = new SqlCommand();
        String connectionString = "";


        public Service1()
        {
            InitializeComponent();
        }
        public String getQuery()
        {
            return "SELECT MessageID FROM dbo.navman_ic_api_message WHERE Proccessed IS NULL";
        }

        public void OnDebug()
        {
            OnStart(null);
        }

        protected override void OnStart(string[] args)
        {
            dependencyCommand.CommandText = getQuery();
            connectionString = "Data Source=";
            connectionString += servidor + ";Initial Catalog=FOO;Persist Security Info=True;User ID=";
            connectionString += SQLuser + ";Password=";
            connectionString += SQLpass + ";Initial Catalog=" + DataB;

            con = new SqlConnection(connectionString);
            try
            {
                con.Open();
            }
            catch (Exception f)
            {
                var logging = new StringBuilder();
                var filePath = @"c:\temp\log.txt";
                String timestamp = DateTime.Now.ToString("[yyyy:MM:dd][HH:mm:ss]");
                logging.Append(timestamp + Environment.NewLine + Environment.NewLine + connectionString + Environment.NewLine + Environment.NewLine + f.ToString() + Environment.NewLine + Environment.NewLine);
                File.AppendAllText(filePath, logging.ToString());
            }
            if (con.State == ConnectionState.Open)
            {
                Initialization();
                dependencyStarter();
                var logging = new StringBuilder();
                var filePath = @"c:\temp\test.txt";
                String timestamp = DateTime.Now.ToString("[yyyy:MM:dd][HH:mm:ss]");
                logging.Append(timestamp + Environment.NewLine + Environment.NewLine + "SUCCESS" + Environment.NewLine + Environment.NewLine);
                File.AppendAllText(filePath, logging.ToString());
            }

        }

        protected override void OnStop()
        {
            Termination();
        }

        void dependencyStarter()
        {
            // Assume connection is an open SqlConnection.

            // Create a new SqlCommand object.
            using (SqlCommand command = new SqlCommand(getQuery(),con))
            {

                // Create a dependency and associate it with the SqlCommand.
                SqlDependency dependency = new SqlDependency(dependencyCommand);
                // Maintain the refence in a class member.

                // Subscribe to the SqlDependency event.
                dependency.OnChange += new
                   OnChangeEventHandler(OnDependencyChange);

                // Execute the command.
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    // Process the DataReader.
                }
            }
        }
        void OnDependencyChange(object sender, SqlNotificationEventArgs e)
        {
            // Handle the event (for example, invalidate this cache entry).
            var logging = new StringBuilder();
            var filePath = @"c:\temp\test.txt";
            String timestamp = DateTime.Now.ToString("[yyyy:MM:dd][HH:mm:ss]");
            logging.Append(timestamp + Environment.NewLine + Environment.NewLine + sender.ToString() + Environment.NewLine + Environment.NewLine);
            File.AppendAllText(filePath, logging.ToString());
        }
        void Termination()
        {
            // Release the dependency.

            SqlDependency.Stop(connectionString);
        }
        void Initialization()
        {
            // Create a dependency connection.
            SqlDependency.Stop(connectionString);
            SqlDependency.Start(connectionString);
        }
    }
}

谢谢,

1 个答案:

答案 0 :(得分:4)

尝试使用SqlDependency。 Detecting Changes with SqlDependency

我已在许多项目中使用过这些项目,但它们似乎运作良好。这使用QueryNotifications,它是SQL Server Service Broker的一部分。

如果Broker尚未激活,则必须启用它。让DBA运行以下内容:

USE master;
GO

ALTER DATABASE MyDatabase SET ENABLE_BROKER;
GO

文章中的示例代码:

void Initialization()
{
    // Create a dependency connection.
    SqlDependency.Start(connectionString, queueName);
}

void SomeMethod()
{
    // Assume connection is an open SqlConnection.

    // Create a new SqlCommand object.
    using (SqlCommand command=new SqlCommand(
        "SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers", 
        connection))
    {

        // Create a dependency and associate it with the SqlCommand.
        SqlDependency dependency=new SqlDependency(command);
        // Maintain the refence in a class member.

        // Subscribe to the SqlDependency event.
        dependency.OnChange+=new
           OnChangeEventHandler(OnDependencyChange);

        // Execute the command.
        using (SqlDataReader reader = command.ExecuteReader())
        {
            // Process the DataReader.
        }
    }
}

// Handler method
void OnDependencyChange(object sender, 
   SqlNotificationEventArgs e )
{
  // Handle the event (for example, invalidate this cache entry).
}

void Termination()
{
    // Release the dependency.
    SqlDependency.Stop(connectionString, queueName);
}

基本上,您在SQL Server中设置一个回调,只要给定查询的结果发生变化,就会调用该回调。然后由你来做点什么。

您可能希望在表格上有一列,以便您可以判断数据是否为新数据。像" CreateDate"或"已处理"。从依赖项查询中排除它。然后你可以在以后使用它来获取新东西。

我应该注意,如果表经常更改,最好定期进行轮询,只需将所有更改作为一个批处理,而不是一次尝试处理它们。 SqlDependency非常适合刷新缓存数据。它不适合处理被用作事务队列的表。

完成后我不会删除数据。只需在下一个查询中忽略它,或者将其移动到存档表。如果您以后需要对其进行故障排除,删除信息通常是一个坏主意。