2009-04-19 23 views
18

¿Es posible acceder a los "mensajes de subproducto" de SQL Server a través de ADO.NET? Debido a la falta de palabras, me refiero a "mensajes de subproductos" que aparecen en la pestaña Mensajes en Microsoft SQL Server Management Studio. Lo que particularmente me importa es leer la salida de SET STATISTICS TIME ON. Parece que SqlDataReader no ofrece nada en este asunto.Acceso a mensajes de SQL Server a través de ADO.NET

Respuesta

24

Sí, hay un evento en la clase SqlConnection llamada SqlInfoMessage, que se puede enganchar en:

SqlConnection _con = 
    new SqlConnection("server=.;database=Northwind;integrated Security=SSPI;"); 

_con.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler); 

El controlador de eventos se verá así:

static void InfoMessageHandler(object sender, SqlInfoMessageEventArgs e) 
{ 
    string myMsg = e.Message;    
} 

El e.Message es el mensaje impreso a la ventana de mensaje en SQL Server Management Studio.

+1

+1 para esto. Ha estado en mis narices en ADO ('OnInfoMessage') por más de una década; Simplemente nunca me gustó lo que era. –

2

Gracias por la respuesta anterior. Acabo de hacer un pequeño experimento y encontré un pequeño error inesperado (¿un error?) Al leer mensajes (en este caso producidos por SET STATISTICS TIME ON) de un resultado de varios registros. Como se indica a continuación, se debe llamar a NextResult incluso después del último conjunto de resultados para obtener el último mensaje. Esto no es necesario en el caso de un solo resultado del conjunto de registros.

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); 
     } 

    } 
} 
+0

Esto sería genial como respuesta a una pregunta separada, p. Ej. "¿Cómo obtengo el último mensaje de información después de ejecutar una consulta que devuelve múltiples conjuntos de resultados?" o algo similar. –

+0

Como comentario sobre el código para cualquiera que no lo sepa, los bucles while vacíos también se pueden escribir como: 'while (rdr.Read());' –

Cuestiones relacionadas