Доступ к сообщениям SQL Server через ADO.NET
Можно ли получить доступ к SQL Server "сообщения о побочных продуктах" через ADO.NET? Из-за отсутствия слов под "сообщениями о побочных продуктах" я подразумеваю вывод, который появляется на вкладке "Сообщения" в Microsoft SQL Server Management Studio. Что мне особенно важно, так это прочитать вывод SET STATISTICS TIME ON. Похоже, что SqlDataReader ничего не предлагает в этом вопросе.
3 ответа
Да, есть событие на 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.
Спасибо за ответ выше. Я просто провел небольшой эксперимент и обнаружил небольшой неожиданный сбой (ошибка?) При чтении сообщений (в данном случае, созданных с помощью команды 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);
}
}
}
Основываясь на ответе 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} ";
}