我有两张表,一张是“评论”,另一张是“待评论”。我希望当我复制“评论”表中“待处理评论”的数据时,应该从“待处理评论”表中删除该数据。
这是我的代码。
<?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_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错误报告,否则无法工作。
还有一个非常重要的警告:
切勿使用
mysqli_multi_query()
!!!
这个功能极其不安全,造成的问题比它解决的问题还要多。事实上,它并不能解决任何问题,只会制造更多问题。 您无法同时从 PHP 运行查询! 如果没有线程或并行化,这是不可能做到的。如果您需要这样的东西,那么您可以查看 Swoole 或 ReactPHP 但您的情况可能不需要它。