Is it possible to access the SQL Server "by-product messages" via ADO.NET? Due to the lack of words, by "by-product messages" I mean the output which appears in the Messages tab in Microsoft SQL Server Management Studio. What I particularly have it mind is to read the output of SET STATISTICS TIME ON. It appears that SqlDataReader does not offer anything in this matter.
Asked
Active
Viewed 5,506 times
3 Answers
31
Yes, there's an event on the SqlConnection
class called SqlInfoMessage
, which you can hook into:
SqlConnection _con =
new SqlConnection("server=.;database=Northwind;integrated Security=SSPI;");
_con.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler);
The event handler will look like this:
static void InfoMessageHandler(object sender, SqlInfoMessageEventArgs e)
{
string myMsg = e.Message;
}
The e.Message
is the message printed out to the message window in SQL Server Management Studio.

Joseph Daigle
- 47,650
- 10
- 49
- 73

marc_s
- 732,580
- 175
- 1,330
- 1,459
-
1+1 for this. It's been under my nose in ADO (`OnInfoMessage`) for over a decade; i just never appreciated what it was. – Ian Boyd Feb 03 '12 at 20:57
-
Is this achievable with `DbConnection`? – Shimmy Weitzhandler Dec 26 '18 at 02:36
-
1@Shimmy: no, sorry - this is a SQL Server specific feature only available on `SqlConnection` – marc_s Dec 26 '18 at 07:12
-
1Thanks for this! I'm now using the VB.NET equivalent `AddHandler _con.InfoMessage, AddressOf InfoMessageHandler` and am delighted with what I can now get from `SET STATISTICS IO ON`. – Magnus Smith Feb 18 '19 at 13:46
5
Thank you for the response above. I just did a little experiment and found a little unexpected glitch (a bug?) when reading messages (in this case produced by SET STATISTICS TIME ON) from a multi-recordset result. As indicated below, one has to call NextResult even after the last resultset in order to get the last message. This is not needed in the case of a single recordset result.
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);
}
}
}

Jan Zich
- 14,993
- 18
- 61
- 73
-
1This would be great as an answer to a separate question, e.g. "How do I get the last info message after executing a query that returns multiple result-sets?" or something similar. – Kenny Evitt Jan 22 '12 at 06:32
-
As a comment on the code for anyone not aware, the empty while loops can also be written like: `while (rdr.Read()) ;` – Samuel Slade Mar 28 '14 at 09:27
-
Jan, thanks for this little piece of gold dust that one has to sprinkle on to make things work. Kudos! This had me stumped for quite a while, and without your write-up I'd probably still be looking for the solution ... – DarthGizka May 07 '23 at 08:00
1
Based on marc_s' answer, I ve created a wrapper class
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;
}
}
Example of use :
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} ";
}

Michael Freidgeim
- 26,542
- 16
- 152
- 170