php - PDO 准备语句返回 0 行,但查询工作正常

标签 php mysql pdo prepared-statement

我有以下准备好的声明:

SELECT `e1`.`field_value` AS `county`,
       `e2`.`field_value` AS `venue_type`,
       `l`.`ID` AS `listing_id`,
       `l`.`ID` AS `id`,
       `l`.`user_ID` AS `user_id`,
       IF(`l`.`user_ID` > 1, 'b', 'a') AS `flag` ,
       COUNT(`img`.`ID`) AS `img_num`
FROM ( `listingsDBElements` `e1`,
       `listingsDBElements` `e2`,
       `listingsDB` `l` )
LEFT JOIN `listingsImages` `img` ON (`l`.`ID` = `img`.`listing_id`
                                     AND `l`.`user_ID` = `img`.`user_id`
                                     AND `img`.`active` = 'yes')
WHERE `e1`.`field_name` = 'county'
  AND `e1`.`field_value` = :county
  AND `l`.`ID` = `e1`.`listing_id`
  AND `l`.`user_ID` = `e1`.`user_id`
  AND `e2`.`field_name` = 'venue_type'
  AND `e2`.`field_value` = :venueType
  AND `l`.`ID` = `e2`.`listing_id`
  AND `l`.`user_ID` = `e2`.`user_id`
  AND `l`.`ID` = `e2`.`listing_id`
  AND `l`.`user_ID` = `e2`.`user_id`
  AND `l`.`active` = 'yes'
GROUP BY `l`.`ID`
ORDER BY `flag` DESC,
         `img_num` DESC LIMIT :limit,
                              :offset

绑定(bind)以下参数:

:county => 'Bedfordshire'
:venueType => 'Conference Centre'
:limit => 0
:offset => 12

然后,我使用 PDO 执行准备好的语句,如下所示:

$vens = $db->prepare($sql);

if($paged)
{
    $limit = (int) (($page - 1) * $perPage);
    $perPage = (int) $perPage;

    $vens->bindParam(':offset', $perPage, PDO::PARAM_INT);
    $vens->bindParam(':limit', $limit, PDO::PARAM_INT);
}

foreach($bindings as $key => $value) { $vens->bindParam($key, $value, PDO::PARAM_STR); }
$vens->execute();

while($ven = $vens->fetchObject())
{
    $_tpl['venues'][] = new Venue($ven->id);
}

即使使用$db->rowCount(),上述内容也始终返回 0 个结果,但如果我手动运行查询并替换 MySQL 中的占位符,则会生成 4 条记录的预期结果。奇怪的是,我有另一个(几乎相同的)查询运行并计算总行数,并绑定(bind)相同的参数,如下所示:

SELECT COUNT(DISTINCT(`l`.`ID`)) AS `total`
FROM ( `listingsDBElements` `e1`,
       `listingsDBElements` `e2`,
       `listingsDB` `l` )
WHERE `e1`.`field_name` = 'county'
  AND `e1`.`field_value` = :county
  AND `l`.`ID` = `e1`.`listing_id`
  AND `l`.`user_ID` = `e1`.`user_id`
  AND `e2`.`field_name` = 'venue_type'
  AND `e2`.`field_value` = :venueType
  AND `l`.`ID` = `e2`.`listing_id`
  AND `l`.`user_ID` = `e2`.`user_id`
  AND `l`.`ID` = `e2`.`listing_id`
  AND `l`.`user_ID` = `e2`.`user_id`
  AND `l`.`active` = 'yes'

上面的执行使用:

$counter = $db->prepare($countSql);
$counter->execute($bindings);
$counts = $counter->fetchObject();

$counts->total 正确返回 4。任何人都可以建议为什么第一个准备语句通过 PDO 返回 0 行,但在手动输入 MySQL 时工作正常?

编辑:

根据 Joachim 的评论,还有其他查询可以在将参数绑定(bind)到限制和偏移量的情况下正常运行,甚至删除它们也会返回相同的结果。例如,以下查询可以正常工作:

SELECT `l`.`ID` AS `id`,
       IF(`l`.`user_ID` > 1, 'b', 'a') AS `flag`
FROM `listingsDB` `l`
INNER JOIN `listingsDBElements` `e` ON `l`.`ID` = `e`.`listing_id`
WHERE `e`.`field_name` = 'city'
  AND `e`.`field_value` = :town
  AND `l`.`active` = 'yes'
ORDER BY `flag` DESC LIMIT :limit,
                           :offset

最佳答案

基本上,您只能在准备好的语句中绑定(bind)某些类型的事物。

来自MySQL manual :

The markers are legal only in certain places in SQL statements. For example, they are permitted in the VALUES() list of an INSERT statement (to specify column values for a row), or in a comparison with a column in a WHERE clause to specify a comparison value. However, they are not permitted for identifiers (such as table or column names), or to specify both operands of a binary operator such as the = equal sign. The latter restriction is necessary because it would be impossible to determine the parameter type. In general, parameters are legal only in Data Manipulation Language (DML) statements, and not in Data Definition Language (DDL) statements.

请注意,LIMIT 和 OFFSET 不在允许的位置列表中。

关于php - PDO 准备语句返回 0 行,但查询工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22253732/

相关文章:

mysql - 使用 MySQL 更新所有表中的外键

javascript - 如何将表单数组传递到函数中的 PHP 脚本?

php - 基数违规 : 1241 Operand should contain 1 column(s) PDO

php - 在管理页面中启用模板路径提示 - Magento

php - 使用选择选项从数据库中选择相关数据,php mysql

php - 热门评论 sql查询

mysql - 比较不同数据库上两个相同表结构的不同数据

php - 如何从 PHP PDO 接收 MYSQL 警告(例如 #1264 Out of Range)

PHP 循环嵌套 JSON 响应并重新组装为 Webhook 的简单查询字符串

php - lastInsertId() 用于准备语句中的更新