MySQL « Запрос WHERE … IN используя prepare PDO

Напоролся на засаду... Не могу понять, как правильно построить запрос (WHERE IN) в PDO.
При обычном построении запроса я бы написал примерно так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }

$params = array(1, 3, 7);
$res = mysql_query("SELECT * FROM users WHERE uid IN (".implode(',',$params).")");
// и т.д.
// В итоге - получаем три записи
 

Наивно надеялся, что в PDO не надо будет ломать голову. Пробовал написать так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .php.geshi_code {font-family:monospace;} .php.geshi_code .imp {font-weight: bold; color: red;} .php.geshi_code .kw1 {color: #b1b100;} .php.geshi_code .kw2 {color: #000000; font-weight: bold;} .php.geshi_code .kw3 {color: #990000;} .php.geshi_code .co1 {color: #666666; font-style: italic;} .php.geshi_code .co2 {color: #666666; font-style: italic;} .php.geshi_code .co3 {color: #0000cc; font-style: italic;} .php.geshi_code .co4 {color: #009933; font-style: italic;} .php.geshi_code .coMULTI {color: #666666; font-style: italic;} .php.geshi_code .es0 {color: #000099; font-weight: bold;} .php.geshi_code .es1 {color: #000099; font-weight: bold;} .php.geshi_code .es2 {color: #660099; font-weight: bold;} .php.geshi_code .es3 {color: #660099; font-weight: bold;} .php.geshi_code .es4 {color: #006699; font-weight: bold;} .php.geshi_code .es5 {color: #006699; font-weight: bold; font-style: italic;} .php.geshi_code .es6 {color: #009933; font-weight: bold;} .php.geshi_code .es_h {color: #000099; font-weight: bold;} .php.geshi_code .br0 {color: #009900;} .php.geshi_code .sy0 {color: #339933;} .php.geshi_code .sy1 {color: #000000; font-weight: bold;} .php.geshi_code .st0 {color: #0000ff;} .php.geshi_code .st_h {color: #0000ff;} .php.geshi_code .nu0 {color: #cc66cc;} .php.geshi_code .nu8 {color: #208080;} .php.geshi_code .nu12 {color: #208080;} .php.geshi_code .nu19 {color:#800080;} .php.geshi_code .me1 {color: #004000;} .php.geshi_code .me2 {color: #004000;} .php.geshi_code .re0 {color: #000088;} .php.geshi_code span.xtra { display:block; }

$params = array(1, 3, 7);
$e = $db-> prepare("SELECT * FROM users WHERE uid IN (?)");
$e -> execute((array(implode(',',$params))));
$e -> setFetchMode(PDO::FETCH_ASSOC);
// Итог - только одна запись
 

Если кто сталкивался с такой проблемой, то прошу подсказать в какую сторону рыть надо.

P.S. Без prepare и плейсхолдеров, естественно, что работает нормально, но это не вариант.

1 ответов


В мане PDO сказано:
> You cannot bind multiple values to a single parameter; for example, you cannot bind two values to a single named parameter in an IN() clause.

Подготовьте сначала строку вида SELECT * FROM users WHERE uid IN (?, ?, ?, ...)
Так, как вы хотели, например. implode etc.
Потом делайте prepare. PDO всё равно откуда пришла строка, так что он съест такие параметры.
Передавайте execute порядковый array со списком значений.


Попробуйте


$pdo = $db->prepare('SELECT * FROM tbl WHERE id IN (value)');
$pdo->bindValue('value', $value);
 

в Zend_Db_Select используется именно PDO. При этом зендовая обертка позволяет писать запросы типа:


->where('id in(?)', $array_of_values);
 
И не имеет значения, массив вы отдали, или строку/число. он правильно компонует запрос.
причем он работает как в комплекте с самим зендом, так и как отдельный компонент. Zend_Db_Select как враппер над PDO очень даже неплох. в любом случае - лучше, чем самописные костыли.