Capture a saída de impressão do procedimento armazenado em .NET

97

É possível capturar a saída de impressão de um procedimento armazenado T-SQL no .NET?

Tenho muitos procs legados que usam a impressão como meio de mensagem de erro. Por exemplo, é possível acessar a saída 'palavra' a partir do PROC seguinte?

-- The PROC
CREATE PROC usp_PrintWord AS
    PRINT 'word'
// Some C# Code to would like to pull out 'word'
SqlCommand cmd = new SqlCommand("usp_printWord", TheConnection);
cmd.CommandType = CommandType.StoredProcedure;
// string ProcPrint = ???
Peter
fonte
4
Talvez não seja apenas sobre erros. Vou tentar usar isso para acompanhar o progresso de um procedimento armazenado de longa execução, observando a saída informativa.
Csaba Toth

Respostas:

143

Você pode fazer isso adicionando um manipulador de eventos para o InfoMessage evento na conexão.

myConnection.InfoMessage += new SqlInfoMessageEventHandler(myConnection_InfoMessage);

void myConnection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    myStringBuilderDefinedAsClassVariable.AppendLine(e.Message);
}
AdaTheDev
fonte
5
Se você também deseja que a contagem de linhas afetadas, você precisa de um manipulador para o evento StatementCompleted no SqlCommand.
Nicholas
@Nicholas você pode explicar? Não consigo fazer com que esse evento funcione corretamente. Consulte stackoverflow.com/questions/27993049/…
Sr. TA
Você está capturando todas as mensagens produzidas no servidor sql com esse evento? É possível que esse evento também capture algumas outras mensagens, não produzidas por esse procedimento armazenado?
FrenkyB
Isso pode ser óbvio, mas se não houver saída do proc (no print, raiseerror, etc.) então o evento não é disparado. Isso me deixou perplexo por um tempo, até que percebi o que estava acontecendo.
IronRod
@FrenkyB posso confirmar que ele irá capturar todas as saídas (impressão, raiserror, etc.) do proc invocado ou quaisquer procs ou funções que ele chamar.
IronRod
9

Isso é realmente útil se você deseja capturar a saída de impressão no console de saída do LinqPad:

SqlConnection conn = new SqlConnection(ConnectionString);
//anonymous function to dump print statements to output console
conn.InfoMessage += (object obj, SqlInfoMessageEventArgs e)=>{
                e.Message.Dump();
            };
BraveNewMath
fonte
1

Para obter a saída em uma variável:

string printOutput = "";

using (var conn = new SqlConnection(...))
{
    // handle this event to receive the print output
    conn.InfoMessage += (object obj, SqlInfoMessageEventArgs e) => {
        printOutput += e.Message;
    };

    // execute command, etc.
}

Console.Write(printOutput);
Keith
fonte