zend框架:如何准备和执行WHERE IN子句?

时间:2011-06-10 11:31:00

标签: php zend-framework pdo

我想准备一个在循环中使用的语句。当我尝试执行该语句时,我在日志中看到错误,上面写着“参数号无效:没有参数被绑定”。

我的代码出了什么问题?

$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));
}

编辑:

我想我的设置中可能有一个错误,这解释了为什么我尝试失败的原因。我看到了这个:

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

编辑:

我使用的是错误的适配器。应该是Zend_Db_Statement_Pdo: - )

感谢您的回复。

3 个答案:

答案 0 :(得分:4)

?不能被数组替换,它必须被标量替换(感谢评论指出这并不总是意味着字符串...脑筋屁在我的结尾)。让我知道这是否更好:

$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 :(得分:1)

您是否尝试过这样做:

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

我不是Zend_framework的专家,但是当你使用语句时,必须使用execute方法

  

如果您使用位置参数,或   那些标有问题的人   标记符号('?'),传递绑定   普通数组中的值。

所以我认为你需要传递一个带有一个值的数组,该值代替“?”在声明中。在这种情况下,你需要一个逗号分隔的字符串(如果你的id是int)来替换语句中的(?)。

如果不破坏值,则执行的操作是传递包含数组的数组。

答案 2 :(得分:1)

您可以使用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(),您可以将ID列表作为单个逗号分隔的字符串传递。您可以安全地使用PHP函数implode()从ID数组生成字符串。

但是,我不确定它是否对性能有任何影响。 我查看了explain的输出,看起来find_in_set()无法使用索引,因此生成具有可变数量参数的查询应该会更好。