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

不问归期 提交于 2019-11-26 04:26:32

问题


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?


回答1:


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.




回答2:


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.




回答3:


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 iii
$bindString = str_repeat('i', count($ids));

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

$stmt->bind_params($bindString, ...$ids);
$stmt->execute();



回答4:


I'll add an ultimately slow & ugly solution which nevertheless uses prepared statements for ANY number of array items :) 3 statements are universal for any case and can be reused everywhere.

  1. CREATE TEMPORARY TABLEids(idINT );
  2. INSERT INTOidsVALUES(?); this will insert your IDs
  3. SELECTidFROMidsLEFT JOIN .... ; use data from other tables to sort the ids list
  4. SELECTidFROMids; select everything back

Otherwise you'll have to use IN (?,?,?,.... or sort the rows manually. The best idea is to use simple MySQL-queries, or, try to get the list of IDs already sorted in the way you like.




回答5:


An alternative would be to use PHP usort function on the result object, but this is "manual."

See this: Sort Object in PHP




回答6:


No, it's not recommended, if you are to fetch certain records from the database using ORDER BY clause.




回答7:


Have you considered rewriting you original query using a JOIN and WHERE clause to get the IDS you need to avoid the need for a WHERE IN clause? I came here with the same question and after reviewing the possible solutions I realized an INNER JOIN was my solution.



来源:https://stackoverflow.com/questions/3703180/a-prepared-statement-where-in-query-and-sorting-with-mysql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!