高效更新SQL,使用一个SQL语句更新多行,避免循环

Jam*_*oll 1 mysql sql sql-update

我正在尝试避免在我正在处理的项目中的循环中进行数据库访问.对SQL不太好,我不确定最好的方法来解决这个问题.

我正在使用多个库存位置/选择位置更新销售过程中的库存级别数据库.

因此,这就是我在做的事情.

循环访问产品ID,然后循环浏览每个产品的选择位置并更新数量,例如:

For Each wProductId In calculatedProds.Keys '' loop through products requested passing values of pick locations
        For i = 0 To locationCount ' split the location value from the string as per above
            Dim thisLocation As Integer = locationID
            Dim thisQty As Integer = qtyPicked                
            Dim sql As String = "UPDATE `stockLevels` SET `stockLevel`=`stockLevel` - '" & thisQty & "' WHERE `stockLocation`='" & thisLocation & "' AND `id`='" & wProductId & "'"
            ' DO DATA ACCESS WITH SQL ABOVE       
        Next
Next
Run Code Online (Sandbox Code Playgroud)

当然这是有效的,但它为每个项目的每个库存位置打开一个新的数据库连接.

那么我将如何将其作为一个更新声明?

http://www.karlrixon.co.uk/writing/update-multiple-rows-with-different-values-and-a-single-sql-query/

我认为,这个链接让我非常接近我所追求的,但我不是100%确定如何动态构建该SQL语句以及如何向CASE添加两个条件.

我需要构建一个SQL语句,如:

UPDATE stockLevels
SET stockLevel= CASE id
    WHEN '"& wProductId  &"' AND stockLocation='"& thisLocation &"' THEN `stockLevel` - '" & thisQty & "'
    WHEN '"& NEXTwProductId  &"' AND stockLocation='"& NEXTthisLocation &"' THEN `stockLevel` - '" & NEXTthisQty & "'
END
Run Code Online (Sandbox Code Playgroud)

但是我在第二个参数添加到CASE的地方不正确!

我像往常一样使用MySQL和VB.NET,非常感谢任何帮助.

a'r*_*a'r 5

由于多种原因,在示例中使用set子句中的case语句并不理想.

  • 没有where子句来帮助数据库有效地执行查询
  • 大量更新的查询大小过大(考虑像这样更新1000行)
  • 您正在手动实现连接 - 数据库几乎可以肯定比您更有效地执行此操作.
  • 调试这样的查询也很困难.

相反,您应该首先一次测量一次更新的性能,看看您是否确实需要进行改进.

如果需要性能改进,那么我建议采用一种方法,首先将更新大量插入临时表中.合适的表格包含以下列:

wProductID, stockLocation, newStockLevel
Run Code Online (Sandbox Code Playgroud)

可以使用以下MySQL语法批量插入更新:

INSERT INTO temp_stock_updates
    (wProductID, stockLocation, newStockLevel)
VALUES
    (?,?,?), (?,?,?), (?,?,?), ...
Run Code Online (Sandbox Code Playgroud)

然后运行单个更新来更新主表.此查询看起来像这样:

UPDATE stockLevels s
    JOIN temp_stock_updates u USING (wProductID, stockLocation)
SET
    s.stockLevel = u.newStockLevel
Run Code Online (Sandbox Code Playgroud)