【问题标题】:PDOStatement query with subqueries returns empty result带有子查询的 PDOStatement 查询返回空结果
【发布时间】:2013-12-26 10:15:37
【问题描述】:

我有以下 PHP 代码,这是一个奇怪的行为。系统采用PostgreSQL数据库,PHP版本为5.3.15。

    $sql = "SELECT ce.id FROM calendar_events AS ce
        WHERE ce.rowid = :rowid
        AND ((SELECT count(*) FROM calendar_events_attendees AS cea WHERE cea.event_id = ce.id AND cea.status <> 'D') > 0
            OR (SELECT count(*) FROM calendar_events_globalfnbl AS ceg WHERE ceg.event_id = ce.id AND ceg.status <> 'D') > 0)";

$stmt = db_prepare($sql); // Creates a PDOStatement
$stmt->bindValue(":rowid", $rowid, PDO::PARAM_INT);
$rv = $stmt->execute();

if($rv) {
    return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
}
else {
    return null;
}

查询执行没有错误,但函数返回一个空数组。数据库中肯定有行可以找到,如果我在 pgAdmin 中执行查询(占位符当然被有问题的 ID 替换),它会返回我想要获取的行。

我设法发现子查询是这里的问题。如果我将它们注释掉并使用以下查询,则会返回行。但当然,这也会返回我尝试用子查询过滤掉的行。

$sql = "SELECT ce.id FROM calendar_events AS ce
        WHERE ce.rowid = :rowid";

PDO 是否根本不支持这种类型的子查询,或者我的代码中是否有任何错误我找不到?

提前致谢!

【问题讨论】:

  • PDO支持子查询,其实它并不关心你的SQL是否包含子查询,问题出在SQL查询本身,而不是PDO。尝试通过命令行或者其他IDE运行这个查询,看看是否执行正确,是否有返回结果。
  • 正如我在问题中所写的,我使用 pdAdmin III 执行了查询。为了确保我只是将代码从这里复制粘贴到 pgAdmin III,将 :rowid 占位符替换为实际 ID 并执行:返回 5 行,正如预期的那样。
  • 该语句返回一个包含结果集中所有剩余行的数组:如果要获取的结果为零,则返回一个空数组,如果失败则返回 FALSE,那么你的内容是什么, true,false,0...(尝试使用 print_r($rv) 和 print_r($stmt->fetchAll))?
  • var_export() 的输出:array()
  • 在我的代码中发现导致此行为的问题,问题现已过时。请参阅下面的答案。

标签: php postgresql pdo subquery pdostatement


【解决方案1】:

我不了解您的框架,但您的 COUNT(*) &gt; 0 子查询似乎等同于 EXISTS (...) 子查询(这也可能更快,因为它们不必计算所有令人满意的元组)

SELECT ce.id 
FROM calendar_events AS ce
WHERE ce.rowid = :rowid
AND ( EXISTS (SELECT *
                FROM calendar_events_attendees AS exa
                WHERE exa.event_id = ce.id AND exa.status <> 'D'
                )
     OR EXISTS (SELECT * 
                FROM calendar_events_globalfnbl AS exg
                WHERE exg.event_id = ce.id AND exg.status <> 'D'
                )
        );

【讨论】:

  • 感谢您的建议,但没有解决我的问题。
【解决方案2】:

这不是 PDO 的问题,而是我的代码本身的问题。在反复检查调用上述函数的代码后,我发现一些语句在执行上述代码之前将相关行的状态设置为“D”。

所以这个问题现在已经过时了,抱歉浪费了你们的时间!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-18
    • 2021-11-20
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    相关资源
    最近更新 更多