什么是激活存储过程368次更新数据库的好方法?

Ben*_*ack 8 .net c# vb.net sql-server stored-procedures

我正在研究一个.NET组件,它从数据库中获取一组数据,对该组数据执行一些业务逻辑,然后通过类似的存储过程更新数据库中的单个记录spUpdateOrderDetailDiscountedItem.

对于小型数据集,这不是问题,但是当我有一个非常大的数据集需要迭代368个存储过程调用来更新数据库中的记录时,我意识到我遇到了问题.一位高级开发人员查看了我的存储过程代码并说它看起来很好,但现在我想探索一种更好的方法来将"批量"数据发送到数据库.

我有哪些选项可以批量更新数据库?这可能与存储过程有关吗?我还有其他选择吗?

我不会选择安装完整的ORM,但任何建议都表示赞赏.


其他背景资料:

我们当前的数据访问模型是在5年前构建的,所有对db的调用当前都是通过模块化/静态函数执行的,其名称ExecQueryGetDataTable.我不确定我是否需要保持在该模型中,但是我必须提供一个非常好的理由来超出我们当前的DAL以进入数据库.

另外值得注意的是,在谈到CRUD操作和数据库时,我还是比较新的.我更喜欢在.NET代码中玩/工作,但数据必须存储在某个地方,对吗?


存储过程内容:

ALTER PROCEDURE [dbo].[spUpdateOrderDetailDiscountedItem] 
    -- Add the parameters for the stored procedure here
    @OrderDetailID decimal = 0,
    @Discount money = 0,
    @ExtPrice money = 0,
    @LineDiscountTypeID int = 0,
    @OrdersID decimal = 0,
    @QuantityDiscounted money = 0,
    @UpdateOrderHeader int = 0,
    @PromoCode varchar(6) = '',
    @TotalDiscount money = 0

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    Update OrderDetail
    Set Discount = @Discount, ExtPrice = @ExtPrice, LineDiscountTypeID = @LineDiscountTypeID, LineDiscountPercent = @QuantityDiscounted
    From OrderDetail with (nolock) 
    Where OrderDetailID = @OrderDetailID

    if @UpdateOrderHeader = -1
      Begin
        --This code should get code the last time this query is executed, but only then.
        exec spUpdateOrdersHeaderForSkuGroupSourceCode @OrdersID, 7, 0, @PromoCode, @TotalDiscount
      End
Run Code Online (Sandbox Code Playgroud)

Not*_*tMe 16

如果您使用的是SQL 2008,则可以使用表值参数在一个s'proc调用中推送所有更新.

更新 顺便提一下,我们将它与merge语句结合使用.这样,sql server负责确定我们是否插入新记录或更新现有记录.此机制在我们的Web应用程序中的几个主要位置使用,并且一次处理数百个更改.在常规加载期间,我们将看到这个proc被调用大约每秒50次,它比我们发现的任何其他方式快得多......当然比购买更大的数据库服务器便宜很多.


Ada*_*rth 9

我在使用中看到的一种简单而另类的方法是构建一个SQL语句,该语句由sql_execs组成,并使用字符串中的参数调用sproc.不确定是否建议这样做,但从.NET的角度来看,你只填充一个SqlCommand并调用ExecuteNonQuery一次......

请注意,如果您选择此项,请使用StringBuilder!:-)

更新:我更喜欢Chris Lively的答案,直到现在还不知道表值参数...不幸的是OP正在使用2005.