【问题标题】:Perform multiple UPDATEs in one SQL query using PHP使用 PHP 在一个 SQL 查询中执行多个 UPDATE
【发布时间】:2024-01-16 02:58:01
【问题描述】:

所以我查看了HERE,但由于我正在做的事情的简单性,这似乎有点令人费解。我最多会处理一百个要更新的项目(而且大部分时间都在进行更像 40 岁)

目前我有这样的东西

$sql_update = '';
for($x = 0; $x < count($nodes); $x++){
  if($nodes[$x]['loaded'] == 'true'){
    if($nodes[$x]['changed'] == 'true'){
        $sql_update .= 'UPDATE `genetic_decomp`.`tbl_node2view` SET `x` = "'.$nodes[$x]['location']['x'].'", `y` = "'.$nodes[$x]['location']['y'].'" WHERE `tbl_node2view`.`id` = "'.$nodes[$x]['id'].'";'; 
        $sql_update .= 'UPDATE `genetic_decomp`.`tbl_nodes` SET `name` = "'.$nodes[$x]['name'].'", `type` = "'.$nodes[$x]['type'].'" WHERE `tbl_nodes`.`node_id` = "'.$nodes[$x]['id'].'";';
    }
  }
}
if($sql_update != ''){
    $sql_result=mysql_query($sql_update,$connection) or exit("Sql Error".mysql_error());
}

现在,当我让它打印出 echo $sql_update 中的输出,然后将输出粘贴到 MAMP 中的 SQL 框中时,它工作正常.. 遍历并更新我想要的两个表中的行

但是,当我运行上面的代码时,它会吐回来:

Sql Error
You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE `genetic_decomp`.`tbl_nodes` SET `name` = "lala", `type` = "p" WHERE `tbl' at line 1

我做错了什么? 有更好的方法吗?

【问题讨论】:

    标签: php mysql sql-update


    【解决方案1】:

    您的 SQL 在语法上看起来是正确的(除非我遗漏了一些简单的东西)。实际问题是因为您使用的是mysql_query() - 支持多个语句;因此,您不能使用此方法同时运行两个 UPDATE 查询。

    来自手册:

    mysql_query() 发送一个唯一的查询(多个查询不是 支持)

    同样,mysql_ 方法已被弃用,因此我(和社区)建议您更新代码以使用 mysqli_PDO 方法 - 这两种方法都支持在单个语句中进行多个查询.

    如果您需要坚持使用mysql_query()(而不是重组整个应用程序),只需拆分查询并背靠背运行它们。

    【讨论】:

    • 谢谢,我没有意识到 mysql_ 方法已经发生了转变,从我的能力来看,mysqli_ 确实看起来好多了
    • 非常感谢!我使用mysqli_multi_query 为我完成了这项工作!
    【解决方案2】:

    如果您使用 mysql_query,则需要单独更新它们。

    【讨论】:

      【解决方案3】:

      作为 mysqli 的替代品,我发现了这个: http://www.karlrixon.co.uk/writing/update-multiple-rows-with-different-values-and-a-single-sql-query/

      想法

      UPDATE categories
          SET display_order = CASE id
              WHEN 1 THEN 3
              WHEN 2 THEN 4
              WHEN 3 THEN 5
          END,
          title = CASE id
              WHEN 1 THEN 'New Title 1'
              WHEN 2 THEN 'New Title 2'
              WHEN 3 THEN 'New Title 3'
          END
      WHERE id IN (1,2,3)
      

      现实生活中的例子

      // An array containing the category ids as keys and the new positions as   values
      $display_order = array(
          1 => 4,
          2 => 1,
          3 => 2,
          4 => 3,
          5 => 9,
          6 => 5,
          7 => 8,
          8 => 9
      );
      
      $ids = implode(',', array_keys($display_order));
      $sql = "UPDATE categories SET display_order = CASE id ";
      foreach ($display_order as $id => $ordinal) {
          $sql .= sprintf("WHEN %d THEN %d ", $id, $ordinal);
      }
      $sql .= "END WHERE id IN ($ids)";
      echo $sql;
      

      我的情况

      我收到的数组

      Array
      (
          [0] => stdClass Object
              (
                  [movement_id] => 278
                  [leg_miles] => 3.5
                  [leg_km] => 5.63
              )
      
          [1] => stdClass Object
              (
                  [movement_id] => 279
                  [leg_miles] => 
                  [leg_km] => 
              )
      
          [2] => stdClass Object
              (
                  [movement_id] => 280
                  [leg_miles] => 
                  [leg_km] => 
              )
      
      )
      

      我的函数(必须使用 sprintf 上的浮点数

          //get ids string
          $ids = "";
          foreach ($movementsData as $movement) {
              $ids .= $movement->movement_id.",";
          }
          $ids = rtrim($ids, ",");
      
          //MySQL query construct
          $sql = "UPDATE movements SET movement_miles = CASE movement_id ";
      
          foreach ($movementsData as $movement) {
              $sql .= sprintf("WHEN %d THEN %.2f ", $movement->movement_id, $movement->leg_miles);
          }
      
          $sql .= "END, ";
      
          $sql .= "movement_km = CASE movement_id ";
      
          foreach ($movementsData as $movement) {
              $sql .= sprintf("WHEN %d THEN %.2f ", $movement->movement_id, $movement->leg_km);
          }
      
          $sql .= "END ";
      
          $sql .= "WHERE movement_id IN (".$ids.")"; 
      

      最终查询结果

      UPDATE movements SET 
          movement_miles = CASE movement_id 
              WHEN 278 THEN 3.50 
              WHEN 279 THEN 0.00 
              WHEN 280 THEN 0.00 
          END, 
          movement_km = CASE movement_id 
              WHEN 278 THEN 5.63 
              WHEN 279 THEN 0.00 
              WHEN 280 THEN 0.00 
          END 
          WHERE movement_id IN (278,279,280)
      

      【讨论】:

        【解决方案4】:

        在php中,你使用mysqli实例的multi_query方法。

        来自php manual

        MySQL 可选择允许在一个语句中包含多个语句 细绳。一次发送多个语句减少了客户端-服务器 往返,但需要特殊处理。

        【讨论】:

          最近更新 更多