1

I have two tables, one 'comment' and the other 'pendingcomment'. I want when I copy the data of the 'pendingcomment' in the 'comment' table then that data should be deleted from the 'pendingcomment' table.

This is my code.

 <?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 ";
}


?>

Result: Error deleting record

Dharman
  • 26,923
  • 21
  • 73
  • 125
  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Apr 25 '21 at 19:55

2 Answers2

1

NEVER USE mysqli_multi_query()!!!

This function is extremely unsafe and causes a lot more problems than it solves. In fact, it doesn't solve any problems, it just creates more. You can't run queries at the same time from PHP! It is impossible to do so without threading or parallelization. If you need something like this then you can check out Swoole or ReactPHP but it's probably not needed in your case.

When executing queries you need to execute them one after another using prepared statements. This is how it should be done properly:

<?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;

The transaction ensures atomicity of the operations as long as your DB engine is InnoDB or a similar transaction engine. MyISAM is not. Remember to enable mysqli error reporting or it won't work.

Dharman
  • 26,923
  • 21
  • 73
  • 125
-2

You are executing two queries, which means you need to denote the end of the first, add a semi-colon ; to the end of your first query to achieve this. Try below, I've added it to both:

$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;";

This question is worth the read, Is it bad to omit semicolon in MySQL queries? which explains the semi-colon usage in more depth

I would also suggest that running these two queries together might cause you some issues, since in the case that your insert fails, you would have still deleted the pendingcomment table record.

Ballard
  • 810
  • 12
  • 25
  • 2
    **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Apr 25 '21 at 20:03
  • 2
    This is unsafe, and it does not execute them in one go. In fact the INSERT can succeed while the DELETE can fail. – Dharman Apr 25 '21 at 20:03
  • 1
    Ok, then if this is not the correct answer why do you suggest it at all? – Dharman Apr 25 '21 at 20:33
  • Because OP has given an example and I've stated why it does not work, alongside giving examples to understand the issue they were getting better and the suggestion about not writing it the way they have – Ballard Apr 25 '21 at 20:35
  • I wish this answer never existed. It's too localized for just a single person while does enormous harm for other people who might take this advise. People are lazy and would stick to the simplest solution despite warnings. For the life of me I won't understand answers like "oh, you're pulling the trigger the wrong way. Here, this is how you can shoot yourself in the head". – Your Common Sense May 28 '22 at 06:10