2009-04-19 7 views
18

Est-il possible d'accéder aux "messages de sous-produits" SQL Server via ADO.NET? En raison du manque de mots, par "messages de sous-produits", j'entends la sortie qui apparaît dans l'onglet Messages de Microsoft SQL Server Management Studio. Ce que j'ai particulièrement l'esprit est de lire la sortie de SET STATISTICS TIME ON. Il semble que SqlDataReader n'offre rien dans ce domaine.Accès aux messages SQL Server via ADO.NET

Répondre

24

Oui, il y a un événement sur le appelé SqlInfoMessage, que vous pouvez brancher en classe SqlConnection:

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

_con.InfoMessage += new SqlInfoMessageEventHandler(InfoMessageHandler); 

Le gestionnaire d'événements ressemblera à ceci:

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

Le e.Message est le message imprimé à la fenêtre de message dans SQL Server Management Studio.

+1

+1 pour cette page. Il a été sous mon nez dans ADO ('OnInfoMessage') pendant plus d'une décennie; Je n'ai jamais vraiment apprécié ce que c'était. –

2

Merci pour la réponse ci-dessus. J'ai juste fait une petite expérience et trouvé un petit problème inattendu (un bug?) Lors de la lecture des messages (dans ce cas produit par SET STATISTICS TIME ON) à partir d'un résultat multi-recordset. Comme indiqué ci-dessous, il faut appeler NextResult même après le dernier resultset afin d'obtenir le dernier message. Cela n'est pas nécessaire dans le cas d'un résultat de jeu d'enregistrements unique.

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

Ce serait une excellente réponse à une question distincte, p. "Comment obtenir le dernier message d'information après l'exécution d'une requête renvoyant plusieurs jeux de résultats?" ou quelque chose de similaire. –

+0

Comme un commentaire sur le code pour quiconque ne sait pas, les boucles while vides peuvent aussi être écrites comme: 'while (rdr.Read());' –

Questions connexes