如何捕获从.NET运行的SQL脚本的输出,包括受影响的行?

时间:2018-01-17 11:08:13

标签: .net sql-server sqlconnection

考虑这个简单的SQL脚本:

PRINT N'Dropping CREATE_TABLE events from DatabaseLog table...'
DELETE FROM [dbo].[DatabaseLog] WHERE Event = N'CREATE_TABLE'
PRINT N'Dropping ALTER_TABLE events from DatabaseLog table...'
DELETE FROM [dbo].[DatabaseLog] WHERE Event = N'ALTER_TABLE'
PRINT N'Done!'

从SSMS运行时,针对AdventureWorks 2012,它会提供此输出:

Dropping CREATE_TABLE events from DatabaseLog table...

(70 row(s) affected)
Dropping ALTER_TABLE events from DatabaseLog table...

(117 row(s) affected)
Done!

如何在.NET中重现这一点,包括受影响的行?

通过挂钩InfoMessage上的SqlConnection事件,我得到PRINT语句的输出,但这不包括受影响行的行。理想情况下,我想捕获输出,就像它在SSMS中运行一样。

注意:脚本是用户提供的,因此修改脚本以手动输出行计数不是一种选择。

2 个答案:

答案 0 :(得分:1)

终于找到了正确的事件来获取个人陈述的数量!单个StatementCompleted上的SqlCommand会多次触发,每次针对影响行的语句触发一次。所以:

public static void ExecuteScript(string connectionString, string sql)
{
    using (var conn = new SqlConnection(connectionString))
    {
        conn.InfoMessage += (sender, args) => Console.WriteLine(args.Message);
        conn.FireInfoMessageEventOnUserErrors = true;
        conn.Open();
        using (var cmd = new SqlCommand(sql, conn))
        {
            cmd.StatementCompleted += (sender, args) =>
                Console.WriteLine($"{Environment.NewLine}({args.RecordCount} row(s) affected)");
            cmd.ExecuteNonQuery();
        }
    }
}
对于我目前为止尝试过的查询,

重现了SSMS的输出,其中包括CREATE TABLEPRINTINSERTDELETE和{ {1}}。

SELECT设置为FireInfoMessageEventOnUserErrors是必要的,否则所有true事件都会显示在最后,而不是与InfoMessage事件正确交错。但是,当StatementCompleted设置为FireInfoMessageEventOnUserErrors时,如果存在错误,则不会抛出true,因此您必须检查每个InfoMessage是否存在错误(如果SqlException设置为> 10)。

答案 1 :(得分:0)

C:\users\brett\Desktop\Microsoft Ads\unityplugins\MainProjects\CommonSource\Microsoft.UnityPlugins.Common\Utils.cs(7,7): error CS0246: The type or namespace name 'Windows' could not be found (are you missing a using directive or an assembly reference?) [C:\users\brett\Desktop\Microsoft Ads\unityplugins\MainProjects\Win10\Microsoft.UnityPlugins.Common\Microsoft.UnityPlugins.Common.csproj] 应该返回受影响的行;

ExecuteNonQuery