Zend Framework: как подготовить и выполнить предложение WHERE IN? - PullRequest
3 голосов
/ 10 июня 2011

Я хочу подготовить оператор для использования внутри цикла. Когда я пытаюсь выполнить оператор, в журналах появляется сообщение об ошибке «Неверный номер параметра: ни один параметр не был связан».

Что не так с моим кодом?

$itemSelectSql = "SELECT * FROM `tblItems` WHERE `itemID` IN (?)";
$itemSelectStmt = new Zend_Db_Statement_Mysqli($this->db_ro, $itemSelectSql);
while () {
  ...
  $itemIds = array();
  // populate $itemIds array
  ...
  $itemSelectStmt->execute(array($itemIds));
}

EDIT:

Я думаю, что у меня может быть ошибка в настройке, которая объясняет, почему все, что я пытаюсь, терпит неудачу. Я вижу это:

PHP Warning:  call_user_func_array() expects parameter 1 to be a valid callback, 
class 'PDOStatement' does not have a method 'bind_param' in 
/var/www/lib/Zend/Db/Statement/Mysqli.php on line 204

EDIT:

Я использовал не тот адаптер. Должно было быть Zend_Db_Statement_Pdo: -)

Спасибо за ответы.

Ответы [ 3 ]

4 голосов
/ 10 июня 2011

? не может быть заменен массивом, его нужно заменить скаляром (спасибо за комментарий, который указал, что это не всегда означает строку ... мозговитость на моем конце). Дайте мне знать, если это работает лучше:

$itemSelectSql = "SELECT * FROM `tblItems` WHERE `itemID` IN ";
while () {
  ...
  $itemIds = array();
  // populate $itemIds array
  ...
  // we need to have the same number of "?,"'s as there are items in the array.
  // and then remove final comma.
  $qs = rtrim(str_repeat("?,", count($itemIds)),',');
  // create a statement based on the result
  $itemSelectStmt = 
       new Zend_Db_Statement_Mysqli($this->db_ro, "$itemSelectSql ($qs)");
  // bind to each of those commas.
  $itemSelectStmt->execute($itemIds);
}
1 голос
/ 10 июня 2011

Вы можете использовать FIND_IN_SET(str,strlist) вместо IN ():

mysql> select id, name from customer where find_in_set(id, '10,15,20');
+----+---------+
| id | name    |
+----+---------+
| 10 | ten     |
| 15 | fifteen |
| 20 | twelve  |
+----+---------+

Таким образом, вам не нужно привязывать массив с несколькими значениями к IN(), вы можете передать список идентификаторов в виде одной строки, разделенной запятыми. Вы можете безопасно использовать PHP-функцию implode() для генерации строки из массива идентификаторов.

Хотя я не уверен, влияет ли это на производительность. Я посмотрел на вывод explain, и похоже, что find_in_set() не может использовать индексы, поэтому генерация запросов с переменным числом параметров должна работать лучше.

1 голос
/ 10 июня 2011

Вы пытались сделать это:

while () {
  ...
  $itemIds = array();
  // populate $itemIds array
  $itemIds = implode(',' $itemIds);
  $itemSelectStmt->execute(array($itemIds));
}

Я не эксперт Zend_framework, но когда вы используете операторы, для метода execute вы должны

Если выиспользуйте позиционные параметры или те, которые отмечены символом вопросительного знака ('?'), передайте значения привязки в виде простого массива.

Так что я думаю, что вам нужно передать массив с одним значениеми это значение заменить на "?"в заявлении.В этом случае вам нужна строка с разделителями-запятыми (если вы идентификаторы int) для замены (?) В операторе.

Что вы делаете, если не взрывают значения, передают массив, содержащий массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...