【问题标题】:Return rows affected from a Stored Procedure on each INSERT to display in ASP.NET page返回每个 INSERT 上受存储过程影响的行以显示在 ASP.NET 页面中
【发布时间】:2012-11-23 03:10:58
【问题描述】:

我有一个包含 10 个不同 INSERT 的存储过程,是否可以将每个 INSERT 上受影响的行的 COUNT 返回到 ASP.NET c# 页面,以便我可以为查看该 ASP.NET 的客户端显示存储过程过程页面?

【问题讨论】:

    标签: c# asp.net sql-server sql-server-2008


    【解决方案1】:

    您需要在存储过程开始时使用以下命令:

    SET NOCOUNT OFF

    在这种情况下,SQL Server 将在每次 INSERT/UPDATE 后实时向客户端发送文本消息(“X 行受影响”)。因此,您只需在软件中阅读这些消息即可。

    这里是my answer how to do it in Delphi,用于 BACKUP MS SQL 命令。抱歉,我对 C# 的了解不够,但我想您可以使用 SqlCommand 类在 C# 中做到这一点。

    【讨论】:

    • 是的!这么多年后,这为我解决了这个问题。太简单。在存储过程中返回 @@RowCount 并且 int count= cmd.ExecuteNonQuery() 给了我受影响的正确记录。我的猜测是我什至不需要将返回 @@RowCount 放入存储过程中。
    【解决方案2】:

    在服务器端使用RAISERROR 函数将消息发送到客户端,严重性为 10(严重性高于 10 会导致异常中断过程执行,即将执行转移到 CATCH 块,如果有的话)。在下面的示例中,我没有添加错误编号,因此RAISERROR 函数将使用默认错误编号 50000。示例如下:

    DECLARE @count INT = 0
    DECLARE @infoMessage VARCHAR(1000) = ''
    
    -- INSERT
    
    SET @count = @@ROWCOUNT
    SET @infoMessage = 'Number of rows affected ' + CAST(@count AS VARCHAR(10))
    RAISERROR(@infoMessage, 10, 0) WITH NOWAIT
    
    -- another INSERT
    
    SET @count = @@ROWCOUNT
    SET @infoMessage = 'Number of rows affected ' + CAST(@count AS VARCHAR(10))
    RAISERROR(@infoMessage, 10, 0) WITH NOWAIT
    

    在客户端,设置适当的事件处理程序,这里是一个例子:

    using (SqlConnection conn = new SqlConnection(...))
    {
        conn.FireInfoMessageEventOnUserErrors = true;
        conn.InfoMessage += new SqlInfoMessageEventHandler(conn_InfoMessage);
        using (SqlCommand comm = new SqlCommand("dbo.sp1", conn) 
               { CommandType = CommandType.StoredProcedure })
        {
            conn.Open(); 
            comm.ExecuteNonQuery();
        }
    }
    
    static void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e)
    {
        // Process received message
    }
    

    【讨论】:

    • 当然,您还有另一项任务,因为您正在将其实现到网页中。这就是如何将异步(例如,每隔几秒)从 SQL Server 到达您的 Web 服务器并最终需要发送到浏览器的进度消息发送到您的 Web 服务器。为此,我推荐 SignalR。
    • .. 每次在 SP 中调用“RAISERROR”都会触发代码中的 event-conn_InfoMessage 吗?
    • 顺便说一句,如果答案是肯定的。我可以使用更新面板(ajax)来显示消息。
    • 是的,就是这样。您可以首先获取此代码,根据您的需要对其进行调整并创建一个作为控制台应用程序的演示,以确保它在控制台应用程序等简单环境中工作。比你必须解决网络应用程序中的整个异步问题。也许UpdatePanel 是可能的(这可能包括轮询服务器以刷新消息),但我相信这会比使用 SignalR 等框架更复杂(并且可能更不可靠)。
    【解决方案3】:

    每次插入后,使用@@ROWCOUNT,然后通过查询获取值。

    返回受最后一条语句影响的行数。如果 行数超过 20 亿,请使用 ROWCOUNT_BIG。

    示例:

    USE AdventureWorks2012;
    GO
    UPDATE HumanResources.Employee 
    SET JobTitle = N'Executive'
    WHERE NationalIDNumber = 123456789
    IF @@ROWCOUNT = 0
    PRINT 'Warning: No rows were updated';
    GO
    

    编辑:如何通过多个查询获得@@rowcount?这是一个例子:

    DECLARE @t int
    DECLARE @t2 int
    SELECT * from table1
    SELECT @t=@@ROWCOUNT
    SELECT * from table2
    SELECT @t2=@@ROWCOUNT
    SELECT @t,@t2'
    

    【讨论】:

    • 如果我有 10 个更新,我如何让每个更新的 @@ROWCOUNT 显示在 asp.net 页面中?或者我如何“通过查询获取值”?
    • 这是一个选项,但它不会“实时”显示 SP 的进程,就在它完成时..
    猜你喜欢
    • 1970-01-01
    • 2014-07-02
    • 2015-12-15
    • 2017-09-22
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多