C#-批处理执行存储过程

C#-批处理执行存储过程,c#,sql,stored-procedures,C#,Sql,Stored Procedures,我目前有一个用C#编写的WinForms应用程序 我们所有的更新都是通过执行存储过程来完成的。我们在一个屏幕上有一种情况,在该屏幕上最多调用60个更新。目前,每个更新调用都会一个接一个地处理,一些客户端和服务器之间连接速度较慢的客户端遇到速度问题。我非常确信,如果我能一次将所有这些调用发送到数据库,这将在客户端节省大量等待时间(目前,对于这60个调用中的每个调用,都会调用ExecuteOnQuery,客户端在继续之前等待真/假结果,这会导致延迟) 将所有这些调用捆绑到一个SQL调用中的最佳方法是

我目前有一个用C#编写的WinForms应用程序

我们所有的更新都是通过执行存储过程来完成的。我们在一个屏幕上有一种情况,在该屏幕上最多调用60个更新。目前,每个更新调用都会一个接一个地处理,一些客户端和服务器之间连接速度较慢的客户端遇到速度问题。我非常确信,如果我能一次将所有这些调用发送到数据库,这将在客户端节省大量等待时间(目前,对于这60个调用中的每个调用,都会调用ExecuteOnQuery,客户端在继续之前等待真/假结果,这会导致延迟)

将所有这些调用捆绑到一个SQL调用中的最佳方法是什么?曾考虑将所有代码放入一个事务中,但需要尽可能避免锁定,因为在任何给定点都有许多并发用户在使用该系统

编辑:存储过程的目的实际上是更新服务器上的记录。我们甚至不需要来自正在执行的存储过程的任何响应。本质上,我想把下面代码中的一组调用捆绑到一个调用中,并想知道这样做的最佳方法是什么

        public virtual bool Update(DataRow dataRow, Guid userId)
    {
        SqlCommand cm = null;
        bool ret = true;
        try
        {
            cm = Utilities.GetSqlUpdateCommand(dataRow, userId);
            ExecuteNonQuery(cm);              
        }
        catch (SqlException ex)
        {
            LogDataAccessBaseError(ex);
            ret = false;
            throw;
        }
        finally
        {
            if (cm != null)
            {
                cm.Dispose();
            }
        }

        return ret;
    }

一个简单的解决方案是实现一个新的存储过程,该存储过程接受必要的参数并在服务器上执行所有必要的存储过程


另一种让它完全位于客户端的方法是,正如您自己指出的,使用事务。因为我不知道存储过程应该做什么,所以我无法在这里说明如何避免锁定。

调用是否需要按特定顺序进行?如果没有,多线程可能会有所帮助


对你的问题最好的回答取决于你对过程的每一端有多大的控制。理想情况下,您只需拨打一个电话,就可以返回包含您所需的所有内容的一大块数据。请记住,当从存储过程返回数据时,存储过程可以返回多个select语句,并且可以循环返回的记录集。因此,一个存储过程可能会返回您需要的所有内容。根据查询所需的参数,将所有内容封装在单个存储过程中可能没有意义,但您可能至少可以将其封装为几个调用。

半同步半异步模式可能会有所帮助。基本上,您将所有请求放入一个队列,然后客户机提取项目


有关抽象概念,请参见。

是否使用SQL Server 2008或更高版本,以及所有存储过程调用是否相同(单个参数除外)

如果是这样,您可以考虑创建一个采用()的存储过程版本。这将允许您将所有行作为单个表传递给SQL server


如果没有,那么我假设
GetSqlUpdateCommand
当前正在使用存储过程名称构造一个
SqlCommand
,并添加适当的参数。另一种方法是:

更改
GetSqlUpdateCommand
,以便它可以接受现有的
SqlCommand
对象。然后,它附加一个新调用
exec StoredProcedure@Parm1、@Parm2、@Parm2
,并添加这些参数。它需要确保为添加的参数使用新名称,这样它就不会与其他
exec
调用冲突。您可能还需要调整此函数,以便它可以检测何时接近可以传递的参数数量限制,此时它应该执行此命令,然后创建一个新命令

例如,它生成一个文本命令,如:

exec MegaProcedure @Parm1,@Parm2,@Parm3
exec MegaProcedure @Parm4,@Parm5,@Parm6
exec MegaProcedure @Parm7,@Parm8,@Parm9

最后,我认为您不了解事务是什么/做什么-它们不会神奇地将多个调用绑定在一起,因此执行时开销/往返时间更少。它们纯粹是一种机制,通过它可以回滚工作,所以它们在这里没有帮助


(事实上,SQL中的每一条语句都在事务内部运行——只是默认情况下,该事务在语句启动时自动打开,并在语句成功完成时提交)

根据您需要的准确性,无锁查询提示可以帮助您避免锁。如果你在和钱打交道,那就忘了我说过的话。但是,如果你处理的是一个网页在过去24小时内收到的点击量,而你不在乎它是否下降了2%,那么它可能会有所帮助。