通过 ADO.NET 访问 SQL Server 消息

Posted

技术标签:

【中文标题】通过 ADO.NET 访问 SQL Server 消息【英文标题】:Access to SQL Server messages via ADO.NET 【发布时间】:2009-04-19 09:45:27 【问题描述】:

是否可以通过 ADO.NET 访问 SQL Server“副产品消息”?由于缺少文字,“副产品消息”是指出现在 Microsoft SQL Server Management Studio 的“消息”选项卡中的输出。我特别想到的是读取 SET STATISTICS TIME ON 的输出。看来 SqlDataReader 在这件事上没有提供任何东西。

【问题讨论】:

【参考方案1】:

是的,SqlConnection 类上有一个名为 SqlInfoMessage 的事件,您可以挂钩:

SqlConnection _con = 
   new SqlConnection("server=.;database=Northwind;integrated Security=SSPI;");

_con.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler);

事件处理程序将如下所示:

static void InfoMessageHandler(object sender, SqlInfoMessageEventArgs e)

    string myMsg = e.Message;            

e.Message 是打印到 SQL Server Management Studio 消息窗口中的消息。

【讨论】:

为此 +1。在 ADO (OnInfoMessage) 中,它在我的眼皮底下已经有十多年了;我只是从不欣赏它是什么。 这可以通过DbConnection实现吗? @Shimmy:不,抱歉 - 这是 SQL Server 特有的功能,仅在 SqlConnection 上可用 谢谢!我现在使用 VB.NET 等效的 AddHandler _con.InfoMessage, AddressOf InfoMessageHandler,我很高兴我现在可以从 SET STATISTICS IO ON 获得什么。【参考方案2】:

感谢您的上述回复。我只是做了一个小实验,在从多记录集结果中读取消息(在这种情况下由 SET STATISTICS TIME ON 产生)时发现了一个意想不到的小故障(错误?)。如下所示,即使在最后一个结果集之后,也必须调用 NextResult 才能获得最后一条消息。如果是单个记录集结果,则不需要这样做。

using System;
using System.Data.SqlClient;

namespace TimingTest

    class Program
    

        static void Main(string[] args)
        

            SqlConnection conn = new SqlConnection("some_conn_str");
            conn.Open();

            conn.InfoMessage += new SqlInfoMessageEventHandler(Message);

            SqlCommand cmd = new SqlCommand("some_sp", conn);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            SqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())  ;

            rdr.NextResult();

            while (rdr.Read())  ;

            // this is needed to print the second message
            rdr.NextResult();

            rdr.Close();

            conn.Close();

        

        static void Message(object sender, SqlInfoMessageEventArgs e)
        
            Console.Out.WriteLine(e.Message);
        

    

【讨论】:

这将是一个单独问题的答案,例如“执行返回多个结果集的查询后,如何获取最后一条信息消息?”或类似的东西。 作为对任何不知道的人的代码的评论,空的while循环也可以写成:while (rdr.Read()) ;【参考方案3】:

基于marc_s' answer,我创建了一个包装类

public class SqlInfoMessageWrapper

     public SqlInfoMessageWrapper(SqlConnection connection)
     
            SqlConnection = connection;
            connection.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler);
      
      public SqlConnection SqlConnection  get; set; 
      public string Message   get; set; 

      void InfoMessageHandler(object sender, SqlInfoMessageEventArgs e)
      
            Message = e.Message;
      
 

使用示例:

    using (SqlConnection connection = new SqlConnection(connectionString))
    
        connection.Open();
        var messageWrapper=new SqlInfoMessageWrapper(connection) ;

        var ret = SqlHelper2.ExecuteNonQuery(connection, CommandType.Text, command, null);
        messages+= $"messageWrapper.Message number of rows affected ret ";
    

【讨论】:

以上是关于通过 ADO.NET 访问 SQL Server 消息的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server之 ADO增删查改 登录demo 带参数的sql语句 插入自动返回行号

C#:通过 ADO.NET 在 SQL Server 2008 上运行事务

通过 C# 使用 ado.net 将值插入 SQL Server 数据库

使用 ADO.NET 将数据表从内存推送到 SQL Server

ADO .NET 与 SQL Server Management Studio - ADO 性能更差

SQL Server 2008 中的事务问题