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

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

【问题讨论】:

    标签: sql-server ado.net


    【解决方案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} ";
        }
    

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 2011-12-20
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-22
      • 2015-03-21
      相关资源
      最近更新 更多