Skip to content
Advertisement

How can I use mysqli to SELECT and both DELETE and RETURN a single row based on WHERE condition

How can I do a mysqli php query so a SELECT request both RETURNS the row AND DELETES the same row in the MySQL DB?

This php script works fine to query and return a single row based on max numerical zipcode (an example) but my modifications do not complete the delete row:

<?php

echo phpversion();
// Create connection
$con = mysqli_connect("localhost", "mysqluser", "mysqlpass", "mysqldb");

// Check connection
if (mysqli_connect_errno()) {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

// Select all from designated assigned bot
$sql = "SELECT * FROM mysqltable WHERE zipsize=( SELECT max(zipsize) FROM mysqltable ) LIMIT 1;";

// Confirm there are results
if ($result = mysqli_query($con, $sql)) {
    // We have results, create an array to hold the results
    // and an array to hold the data
    $resultArray = array();
    $tempArray = array();
    // Loop through each result
    while ($row = $result->fetch_object()) {

        // Add each result into the results array
        $tempArray = $row;

        array_push($resultArray, $tempArray);
    }

    // Encode the array to JSON and output the results
    echo json_encode($resultArray);
}

// Close connections
mysqli_close($con);
?>

I tried adding this line in various places to delete the row to no success using Id, which is a unique code for every row in the table (also tried with $result and $resultArray instead of $row):

$delsql= mysqli_query($conn,"DELETE FROM mysqltable WHERE Id= $row['Id']"); 

Advertisement

Answer

If you want to select the data and then immediately delete that selected data then you need to run two separate queries. I don’t really know why you have so much unnecessary code there, but I would do it this way:

<?php

// Create connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$con = new mysqli("localhost", "mysqluser", "mysqlpass", "mysqldb");
$mysqli->set_charset('utf8mb4'); // always set the charset

// Select all from designated assigned bot
$sql = 'SELECT * FROM mysqltable WHERE zipsize=( SELECT max(zipsize) FROM mysqltable ) LIMIT 1';
$resultArray = $con->query($sql)->fetch_all(MYSQLI_ASSOC);
echo json_encode($resultArray);

// now delete
$sql = 'DELETE FROM mysqltable WHERE zipsize=( SELECT max(zipsize) FROM mysqltable ) LIMIT 1';
$resultArray = $con->query($sql);

If you don’t need nested arrays and you only ever fetch a single row then you can replace fetch_all(MYSQLI_ASSOC) with fetch_assoc() instead.

Careful! These queries can have unexpected results due to the possibility of selecting a different row than the one you delete unless you specify ORDER BY.

If you have a primary/unique key in the table to uniquely identify the rows you are selecting/deleting then you can store the list of ids and then execute a WHERE IN() query.

For example:

// Select all from designated assigned bot
$sql = 'SELECT * FROM mysqltable WHERE zipsize=( SELECT max(zipsize) FROM mysqltable )';
$resultArray = $con->query($sql)->fetch_all(MYSQLI_ASSOC);
echo json_encode($resultArray);

// get all ids from our array
$ids = array_column($resultArray, 'Id');

// now delete
$sql = 'DELETE FROM mysqltable WHERE Id IN('.str_repeat('?,', count($ids) - 1) . '?)';
$stmt = $con->prepare($sql);
$stmt->bind_param(str_repeat('s', count($ids)), ...$ids);
$stmt->execute();
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement