Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A prepared statement, `WHERE .. IN(..)` query and sorting — with MySQL

Imagine we have a query:

SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`;

and an array of IDs to fetch: $ids = array(1,5,18,25)

With prepared statements it's adviced to prepare one statement and call it multiple times:

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;');
foreach ($ids as $id){
    $stmt->bind_params('i', $id);
    $stmt->exec();
}

But now I'll have to sort the results manually. Do I have any nice alternatives?

like image 298
kolypto Avatar asked Sep 13 '10 18:09

kolypto


People also ask

What is a prepared statement in MySQL?

A prepared statement is a feature used to execute the same (or similar) SQL statements repeatedly with high efficiency. Prepared statements basically work like this: Prepare: An SQL statement template is created and sent to the database. Certain values are left unspecified, called parameters (labeled "?").

What is the SQL query to release the prepared statement which is created using prepare function?

2, “EXECUTE Statement”). DEALLOCATE PREPARE releases a prepared statement (see Section 13.5. 3, “DEALLOCATE PREPARE Statement”).

What is prepared statement in SQL?

The PREPARE statement is used by application programs to dynamically prepare an SQL statement for execution. The PREPARE statement creates an executable SQL statement, called a prepared statement, from a character string form of the statement, called a statement string.

Which version of MySQL introduced the prepared statements?

The prepared statement protocol was introduced in MySQL 4.1 and adds a few new commands: COM_STMT_PREPARE.


3 Answers

you could do it this way:

$ids = array(1,5,18,25);

// creates a string containing ?,?,? 
$clause = implode(',', array_fill(0, count($ids), '?'));


$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $clause . ') ORDER BY `name`;');

call_user_func_array(array($stmt, 'bind_param'), $ids);
$stmt->execute();

// loop through results

Using this you're calling bind_param for each id and you have sorting done by mysql.

like image 198
sled Avatar answered Sep 23 '22 22:09

sled


Had the same problem and in addition to the answer of @sled 7 years ago, here is a possibility without making the call_user_func_array(array($stmt, 'bind_param'), $ids); step, but only call bind_params once:

$ids = array(1,5,18,25);

// creates a string containing ?,?,? 
$bindClause = implode(',', array_fill(0, count($ids), '?'));
//create a string for the bind param just containing the right amount of s 
$bindString = str_repeat('s', count($ids));

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $bindClause . ') ORDER BY `name`;');

$stmt->bind_param($bindString, ...$ids);
$stmt->execute();
like image 14
Fabian N. Avatar answered Sep 23 '22 22:09

Fabian N.


I believe this is the simplest possible answer :

$ids = [1,2,3,4,5];
$pdos = $pdo->prepare("SELECT * FROM somwhere WHERE id IN (:"
        . implode(',:', array_keys($ids)) . ") ORDER BY id");

foreach ($ids as $k => $id) {
    $pdos->bindValue(":". $k, $id);
}

$pdos->execute();
$results = $pdos->fetchAll();

So long your array of Ids does not contain keys or keys with illegal characters, it wil work.

like image 6
Martin J. Avatar answered Sep 26 '22 22:09

Martin J.