Можно ли получить доступ к SQL-сообщениям "побочным продуктом" через ADO.NET? Из-за отсутствия слов, "сообщениями по продукту" я подразумеваю вывод, который появляется на вкладке "Сообщения" в 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.
Ответ 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);
}
}
}
Ответ 3
Основываясь на ответе 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} ";
}