【问题标题】:How to run multiple queries in one time in mysql and php如何在mysql和php中一次运行多个查询
【发布时间】:2021-07-19 05:54:22
【问题描述】:

我有两张表,一张是“评论”,另一张是“待定评论”。我希望当我在“评论”表中复制“待定评论”的数据时,应该从“待定评论”表中删除该数据。

这是我的代码。

 <?php
include '../conn.php';

$id = $_GET['id'];

    
// sql to Insert and  delete a record
$sql = "INSERT INTO comment (blogid, name, email, subject, message, date) SELECT blogid, name, email, subject, message, date FROM pendingcomment WHERE id= $id"; 
$sql .= "DELETE FROM pendingcomment WHERE id=$id";

if (mysqli_multi_query($conn, $sql)) {
    // mysqli_close($conn);
    header('Location: ../pendingcomments.php'); //redirect to the pending page
    exit;
}
 else {
    echo "Error deleting record ";
}


?>

结果:删除记录出错

【问题讨论】:

标签: php mysqli mysqli-multi-query


【解决方案1】:

永远不要使用mysqli_multi_query()!!!

这个函数非常不安全,导致的问题比它解决的问题多得多。事实上,它并没有解决任何问题,它只是创造了更多。 您不能同时从 PHP 运行查询! 如果没有线程或并行化,这是不可能的。如果您需要这样的东西,那么您可以查看SwooleReactPHP,但您的情况可能不需要。

执行查询时,您需要使用准备好的语句一个接一个地执行它们。这应该是正确的做法:

<?php

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli('localhost', 'user', 'password', 'test');
$conn->set_charset('utf8mb4'); // always set the charset

$id = $_GET['id'];

// begin atomic transaction
$stmt = $conn->begin_transaction();

// prepare statement for insert
$stmt = $conn->prepare('INSERT INTO comment (blogid, name, email, subject, message, date) SELECT blogid, name, email, subject, message, date FROM pendingcomment WHERE id= ?');
$stmt->bind_param('s', $id);
$stmt->execute();

// prepare statement for delete
$stmt = $conn->prepare('DELETE FROM pendingcomment WHERE id=?');
$stmt->bind_param('s', $id);
$stmt->execute();

// commit transaction
$conn->commit();

header('Location: ../pendingcomments.php'); //redirect to the pending page
exit;

只要您的数据库引擎是 InnoDB 或类似的事务引擎,事务就可以确保操作的原子性。 MyISAM 不是。 记得开启mysqli报错,不然就不行了。

【讨论】:

    【解决方案2】:

    您正在执行两个查询,这意味着您需要表示第一个查询的结尾,在第一个查询的末尾添加一个分号; 以实现此目的。试试下面,我已经将它添加到两者中:

    $sql = "INSERT INTO comment (blogid, name, email, subject, message, date) SELECT blogid, name, email, subject, message, date FROM pendingcomment WHERE id= $id;"; 
    $sql .= "DELETE FROM pendingcomment WHERE id=$id;";
    

    这个问题值得一读,Is it bad to omit semicolon in MySQL queries? 更深入地解释了分号的用法

    我还建议同时运行这两个查询可能会给您带来一些问题,因为在插入失败的情况下,您仍然会删除pendingcomment 表记录。

    【讨论】:

    • 警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。它们由PDOMySQLi 提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行,you are still in risk of corrupting your dataEscaping is not enough!
    • 这是不安全的,它不会一次性执行它们。事实上,INSERT 可以成功,而 DELETE 可以失败。
    • 请阅读我的回答@Dharman - 已记下这一点
    • 好的,那如果这不是正确的答案,你为什么要建议呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 2018-12-19
    • 2018-12-17
    • 2016-02-09
    相关资源
    最近更新 更多