Доступ к сообщениям SQL Server через ADO.NET - PullRequest
22 голосов
/ 19 апреля 2009

Можно ли получить доступ к SQL Server "побочные сообщения" через ADO.NET? Из-за отсутствия слов под «побочными сообщениями» я подразумеваю вывод, который появляется на вкладке «Сообщения» в Microsoft SQL Server Management Studio. Что я имею в виду, так это прочитать вывод SET STATISTICS TIME ON. Похоже, что SqlDataReader ничего не предлагает в этом вопросе.

Ответы [ 3 ]

28 голосов
/ 19 апреля 2009

Да, в классе 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.

3 голосов
/ 19 апреля 2009

Спасибо за ответ выше. Я только что провел небольшой эксперимент и обнаружил небольшой неожиданный сбой (ошибка?) При чтении сообщений (в данном случае, производимых 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);
        }

    }
}
1 голос
/ 30 ноября 2018

Основываясь на ответе marc_s , я создал класс-оболочку

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} ";
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...