在.NET中捕获存储过程的打印输出


97

是否可以从.NET中的T-SQL存储过程捕获打印输出?

我有很多使用打印作为errorMessaging手段的旧式proc。例如,是否可以从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 = ???

4
也许不仅是关于错误。我将通过观察信息输出来尝试使用它来跟踪长时间运行的存储过程的进度。
Csaba Toth

Answers:


143

您可以通过在连接上的InfoMessage事件中添加事件处理程序来实现。

myConnection.InfoMessage += new SqlInfoMessageEventHandler(myConnection_InfoMessage);

void myConnection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    myStringBuilderDefinedAsClassVariable.AppendLine(e.Message);
}

5
如果还希望受影响的行计数,则需要SqlCommand上StatementCompleted事件的处理程序。
尼古拉斯2014年

@尼古拉斯你能详细说明吗?我无法使该事件正常运行。请参阅stackoverflow.com/questions/27993049/...
大先生

您是否正在捕获该事件在sql Server中生成的所有消息?此事件是否可能还会捕获该存储过程未生成的其他消息?
FrenkyB 2015年

这可能很明显,但是如果proc没有输出(没有打印,raiseerror等),则不会触发该事件。这让我难过了一段时间,直到我意识到发生了什么。
IronRod

@FrenkyB我可以确认它会捕获被调用的proc或其调用的任何proc或函数的所有输出(打印,raiserror等)。
IronRod

9

如果要在LinqPad的输出控制台中捕获Print输出,这非常方便:

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

1

要将输出转换为变量:

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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.