【问题标题】:Mysqli Multi QueryMysqli 多查询
【发布时间】:2016-07-06 23:00:31
【问题描述】:

那么除了我没有包含的数据库连接器之外,还有什么可能导致我收到此错误?

您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在“UPDATE EventData SET deviceID = "631403956MB21" WHERE deviceID = "4631403956MB' at line 1" 附近使用正确的语法

这是我的 php mysqli 多查询。

  $sql =  "UPDATE Device      SET deviceID = \"631403956MB21\" WHERE
  deviceID = \"4631403956MB2\"   ";

  $sql .= "UPDATE EventData   SET deviceID = \"631403956MB21\" WHERE
  deviceID = \"4631403956MB2\"   ";

  $sql .= "UPDATE NotifyQueue SET deviceID = \"631403956MB21\" WHERE
  deviceID = \"4631403956MB2\"   ";

  $sql .= "UPDATE RuleTrigger SET deviceID = \"631403956MB21\" WHERE
  deviceID = \"4631403956MB2\"   ";

  $sql .= "UPDATE RuleList    SET deviceID = \"631403956MB21\" WHERE
  deviceID = \"4631403956MB2\"   ";

  $result = mysqli_multi_query($db, $sql);

  if ($result)  {
      echo 'true';   
  } else {
      echo 'false';         
      echo mysqli_error($db);   
  }

  mysqli_close($db);

谢谢, 迈克

【问题讨论】:

  • 为了使您的代码更易于阅读,请在双引号字符串中使用单引号,例如 $sql = "UPDATE Device SET deviceID = '631403956MB21' WHERE deviceID = '4631403956MB2'";
  • 您是否尝试更改该语句中的主键?
  • 您以错误的方式运行 mysqli_multi_query。更好地以通常的循环方式运行单独的查询 - 它会给您带来更少的问题。
  • 这种情况正是multi_query 存在的原因。它比在循环中执行单个查询要快得多,所以我建议 OP 学习如何正确使用它。发布的代码的唯一问题是查询没有被;分隔。

标签: php mysqli php-5.5


【解决方案1】:

在插入/更新多个查询并使用循环时禁用自动提交:

$mysqli = dbConnect(); // Connect with database
$mysqli->autocommit(FALSE); // Set autocommit off

// You can prepare and bind outside the foreach loop, so you don't 
// have to write and bind each query individually.

$sql = "UPDATE RuleList SET deviceID = ? WHERE deviceID = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('ii', $deviceID1, $deviceID2);

foreach($ids as $id):
    $deviceId1 = $id;
    $stmt->execute();
endforeach;

$stmt->close();
$mysqli->commit(); // Commit all queries
$mysqli->close();

以上是一个例子

【讨论】:

  • 感谢您最近的贡献。看来你知道你在说什么——这里很少见。请访问更多。
  • @YourCommonSense 放下那些花时间帮助你的人真的不好。 @rhazen 您的解决方案很有趣,谢谢分享。我使用您的方法和我的方法进行了一些时间测试,更新了 3,000 行,结果非常不同。通过创建一个准备好的语句并像你一样在循环中调用execute,这个过程在我的设置中持续了大约 550 毫秒。通过转义变量、构建查询数组并使用单个 multi_query 调用,就像我在我的解决方案中所做的那样,相同的数据库更新只需要大约 7 毫秒。快了近 100 倍。
  • @BeetleJuice 你确定你使用了包括交易在内的所有代码吗?
  • @BeetleJuice 没有测试任何速度,但我的印象是使用准备好的语句自动提交更快,再次,没有测试它,虽然它更节省,没有绑定参数你的打开到 SQL 注入。
  • 谢谢你。感谢所有帮助和建议。
【解决方案2】:

正确查询:

UPDATE Device      SET deviceID = '631403956MB21' WHERE deviceID = '4631403956MB2';
UPDATE EventData   SET deviceID = '631403956MB21' WHERE deviceID = '4631403956MB2';
...

所以,最后,你没有分配“;”在每个查询结束时。你只分配一个“;”在php代码的末尾。

$sql =  "UPDATE Device      SET deviceID = \"631403956MB21\" WHERE
deviceID = \"4631403956MB2\"   ";
$sql .= "UPDATE EventData   SET deviceID = \"631403956MB21\" WHERE
deviceID = \"4631403956MB2\"   ";
...

↓↓↓

$sql =  "UPDATE Device      SET deviceID = '631403956MB21' WHERE
deviceID = '4631403956MB2';   ";
$sql .= "UPDATE EventData   SET deviceID = '631403956MB21' WHERE
deviceID = '4631403956MB2';   ";
...

请尝试,希望对您有所帮助。

【讨论】:

    【解决方案3】:

    你不应该在同一个查询中有多个UPDATE 子句。您正在尝试使用mysqli_multi_query,但您需要用分号分隔查询:

    首先创建一个数组:

    $queries = [
        "UPDATE Device...",
        "UPDATE EventData...",
        "UPDATE NotifyQueue...",
    ];
    

    从那里你有两个选择。首先是循环并一次执行一个查询

    foreach($queries as $sql):
        $result = mysqli_query($db, $sql);
        ...
    endforeach;
    

    但这不是一个好主意,因为它需要多次访问数据库。更好的选择是您实际尝试做的事情:执行多查询语句

    $multi_query = implode('; ',$queries);
    mysqli_multi_query($db, $multi_query);
    ...
    

    重要提示

    multi_query 不使用prepared statements,所以如果你不小心,你很容易受到SQL 注入攻击。使用这种方法,请务必先转义字符串并将所有数值转换为数字(例如:$var = (int)$var),然后再将它们包含在查询中。

    顺便说一句,我注意到您在多个表上对deviceID 进行了相同的更改。这可能表明您的架构设计不佳。如果你有 InnoDB 表,你可以使用主键和外键来表示 EventDataNotifyQueue... 表中的 deviceID 是链接到 Device 表中的主键的外键。然后,如果您将更改设置为更新时的级联,您需要做的就是更改 Device 表中的 ID,数据库将负责在其他任何地方更改它。这是quick intro to the concept

    【讨论】:

    • 这几乎不是一个答案。想发表评论时使用 cmets
    • 谢谢;你在重写的时候抓住了我。如果修改后的答案让您满意,请删除反对票。
    猜你喜欢
    • 1970-01-01
    • 2013-09-23
    • 2013-04-29
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    相关资源
    最近更新 更多