Przechwytywanie danych wyjściowych procedury składowanej w .NET

97

Czy jest możliwe przechwycenie wydruku z procedury składowanej T-SQL w .NET?

Mam wiele starszych procesów, które używają print jako środka do przesyłania komunikatów o błędach. Na przykład, czy można uzyskać dostęp do nadruku „słowo” z następującej procedury PROC?

-- 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 = ???
Piotr
źródło
4
Może nie tylko o błędach. Spróbuję użyć tego do śledzenia postępu długo działającego przechowywanego procesu, obserwując wyjście informacyjne.
Csaba Toth

Odpowiedzi:

143

Możesz to zrobić, dodając procedurę obsługi zdarzeń do zdarzenia InfoMessage w połączeniu.

myConnection.InfoMessage += new SqlInfoMessageEventHandler(myConnection_InfoMessage);

void myConnection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    myStringBuilderDefinedAsClassVariable.AppendLine(e.Message);
}
AdaTheDev
źródło
5
Jeśli chcesz również, aby liczba wierszy, na które ma to wpływ, potrzebujesz programu obsługi dla zdarzenia StatementCompleted w SqlCommand.
Nicholas
@Nicholas czy możesz rozwinąć? Nie mogę sprawić, by to wydarzenie działało poprawnie. Zobacz stackoverflow.com/questions/27993049/…
Mr. TA
Czy przechwytujesz wszystkie komunikaty generowane na serwerze sql z tym zdarzeniem? Czy jest możliwe, że to zdarzenie przechwyci również inne komunikaty, które nie zostały wygenerowane przez tę procedurę składowaną?
FrenkyB
Może to być oczywiste, ale jeśli nie ma wyjścia z proc (brak wydruku, zgłoszenie błędu itp.), To zdarzenie nie jest wyzwalane. Zaskoczyło mnie to na chwilę, aż zdałem sobie sprawę, co się dzieje.
IronRod
@FrenkyB Mogę potwierdzić, że przechwyci wszystkie dane wyjściowe (print, raiserror itp.) Z wywoływanego proca lub wszelkich procsów lub funkcji, które wywołuje.
IronRod
9

Jest to bardzo przydatne, jeśli chcesz przechwycić wydruk w konsoli wyjściowej 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
źródło
1

Aby uzyskać dane wyjściowe w zmiennej:

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
źródło