MySQLi, используя IN в где - PullRequest
       12

MySQLi, используя IN в где

3 голосов
/ 17 июля 2010

Привет, у меня возникли некоторые проблемы с использованием IN в предложении where с использованием MySQLi, это мой запрос:

SELECT * FROM core_tags WHERE tag_id IN (1,2,3,4,5) GROUP BY tag_id ORDER BY tag_popularity ASC

Если я запустил это в PHP My Admin, то я получу 5 результатов, как ябудет ожидать.Однако, если я запускаю его на PHP со следующим кодом, я получу только один результат tag_id '1'.

Вот мой PHP.Первоначально я запускал его с использованием функций в классе, но я вручную закодировал его, чтобы проверить, что это не просто ошибка в моих функциях с той же проблемой.

$mysqli = new mysqli(DB_SERVER, DB_NAME, DB_PASSWORD, DB_NAME);
$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN (?) GROUP BY tag_id ORDER BY tag_popularity ASC';
$stmt = $mysqli->prepare($rawQuery);
$stmt->bind_param("s", $tag_ids);
$tag_ids = "1,2,3,4,5";
$stmt->execute();
$stmt->bind_result($tag_id, $tag_name, $tag_desc, $tag_popularity);

while ($stmt->fetch()) {
    printf ("%s\n", $tag_name);
}

$stmt->close();
die();

Кто-нибудь знает, почемуверсия mysqli возвращает только одну строку?Использование mysql вместо mysqli также работает нормально, как и PHP My Admin.

Ответы [ 2 ]

3 голосов
/ 17 июля 2010

Использование подготовленного к строке оператора приведет к тому, что ваш окончательный SQL будет выглядеть так:

IN ('1,2,3,4,5')

с кавычками, а это не то, что вам нужно.Я бы сделал следующее:

$ids= array(1,2,3,4,5);
$mysqli = new mysqli(DB_SERVER, DB_NAME, DB_PASSWORD, DB_NAME);

$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN (';
$rawQuery .= implode(',',array_fill(0,count($ids),'?'));
$rawQuery .= ') GROUP BY tag_id ORDER BY tag_popularity ASC';
$stmt = $mysqli->prepare($rawQuery);
call_user_func_array(array($stmt,'bind_param'),$ids);
$stmt->execute();
$stmt->bind_result($tag_id, $tag_name, $tag_desc, $tag_popularity);

while ($stmt->fetch()) {
    printf ("%s\n", $tag_name);
}

Если implode array_fill сбивает с толку, это просто сокращенный способ создания массива того же размера, что и $ids, заполненного "?", тогдапревращение их в csv.

ОБНОВЛЕНИЕ: путь без привязки параметров

Конечно, если вы хотите пропустить бессмысленную привязку параметров, и вы можете доверять списку$ids для того, чтобы уже очистить, вы можете просто сделать это вместо этого и пропустить раздел bind_params:

$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN (';
$rawQuery .= implode(',',$ids);
$rawQuery .= ') GROUP BY tag_id ORDER BY tag_popularity ASC';

Если вы не можете доверять данным:

function clean_ids(&$item){
 $item = intval($item);
}

$clean_ids = array_walk($ids,'clean_ids');
$rawQuery = 'SELECT * FROM core_tags WHERE tag_id IN (';
$rawQuery .= implode(',',$clean_ids);
$rawQuery .= ') GROUP BY tag_id ORDER BY tag_popularity ASC';
2 голосов
/ 17 июля 2010

Я не уверен насчет PHP, но обычно, когда вы создаете параметризованный запрос, например, тот, который вы создаете, используя только один параметр для списка параметров в «IN», вы можете получить что-то вроде: *

select * from core_tags WHERE tag_id IN ('1,2,3')

это не будет делать то, что вы хотите ... вам нужно добавить параметр в запрос для каждого значения в IN, который вы хотите

...