2011-11-23 113 views
1

我目前有一个使用C#编写的WinForms应用程序。C# - 批处理执行存储过程

我们所有的更新都是通过执行存储过程完成的。我们在一个屏幕上有一个情况,在该屏幕上有多达60个更新。目前,每次更新呼叫都会逐一处理,而且客户端和服务器之间连接速度较慢的某些客户端遇到速度问题。我非常确定,如果我可以一次将所有这些调用发送到数据库,那么它会节省很多客户端的等待时间(目前对于这60个调用中的每一个来说,ExecuteNonQuery被调用并且客户机等待在继续之前为true/false结果,这导致延迟)。

将所有这些调用捆绑到一个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; 
    } 

回答

0

一个简单的解决办法是实现一个新的存储过程,采取必要的参数和在服务器上执行所有必要的存储过程。

另一种完全在客户端完全实现的方式是,正如您自己指出的那样,使用事务。由于我对你的存储过程应该做什么一无所知,所以我不能说在这里如何避免锁定。

0

是否需要按特定顺序进行呼叫?如果不是,多线程可能会有所帮助。

您的问题的最佳答案取决于您对过程的每一端有多少控制权。理想情况下,您只需进行一次调用即可返回一大块包含您需要的数据的数据。请记住,从存储过程返回数据时,存储过程可以返回多个select语句,并且可以遍历返回的记录集。所以一个存储过程可能会返回你需要的一切。也许根据查询需要什么参数将所有内容封装在一个存储过程中是没有意义的,但是至少可以将它包含到少数几个调用中。

+0

根据您需要什么样的准确性,NO LOCK查询提示可以帮助您避免锁定。如果你在处理金钱,那么忘记我甚至说过。但是,如果您处理的是网页在过去24小时内收到的点击次数,并且您不在乎它是否已关闭2%,那么它可能会有所帮助。 –

0

您使用的是SQL Server 2008或更高版本,并且所有存储过程调用都是相同的(除个别参数外)?

如果是这样,您可以考虑创建一个需要Table-Valued ParameterADO)的存储过程的版本。这将允许您将所有行传递到SQL Server作为单个表。


如果没有,那么我假定GetSqlUpdateCommand目前正在建造与所存储的程序名称的SqlCommand并添加适当的参数。一种不同的方法是:

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

E.g.它建立起来像一个文本命令:

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

最后,我想你不明白交易是/不 - 他们没有神奇的多个调用捆绑在一起,使他们以更少的开销/往返执行倍。它们纯粹是一种简单的工作可以回滚的机制,所以它们在这里不起作用。

(而且,事实上,在SQL每条语句在事务内运行无论如何 - 它只是在默认情况下,该交易将自动一份声明中启动时打开,并在该语句成功完成承诺)