如何在另一个查询的while循环中进行第二次PDO mysql查询?

时间:2012-11-02 20:03:20

标签: php mysql pdo

因此,如果我运行这样的查询,那么我正在使用PDO MySQL的一个障碍:

$db->pquery("SELECT `category_id`, `category_name` FROM `database_categorys` ORDER BY `category_name` ASC");
while ($category = $db->fetch())
{
}

在while循环中我不能再做一个查询,否则会取消之前的查询,有没有办法解决这个问题?

这是我的pquery btw:

// A plain query
public function pquery($sql)
{
    $this->STH = $this->database->prepare($sql);  

    $this->counter++;

    return $this->STH->execute();
}

我的获取功能:

public function fetch()
{
    $this->STH->setFetchMode(PDO::FETCH_ASSOC); 
    return $this->STH->fetch();
}

2 个答案:

答案 0 :(得分:3)

这不是PDO限制,它是MySQL客户端库的限制。 MySQL一次只支持一个正在进行的查询。当第一个查询仍然有一个打开的游标时(即它仍然有返回的结果),你不能执行另一个查询。

您有以下选择:

  • 使用PDOStatement::fetchAll()并在PHP数组中收集外部查询的整个结果集。这样就完成了外部查询的查询结果。然后,您可以遍历数组并为每个循环迭代运行一个额外的SQL查询。

    但是为外部结果集的每个循环迭代运行一个新查询效率不高。这是破坏应用程序性能的好方法。

    有些人将此称为N+1 Selects Problem,因为您运行第一个选择,返回N行,然后根据第一个选择的结果运行N个选择。

  • 如果您使用MySQL,请使用基本上做同样事情的PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,下载所有行,并在内部保存在数组中。然后对fetch()的后续调用只是迭代缓冲的结果。

    但这也涉及N + 1选择反模式。

  • 最好编写一个SQL查询来获取所需的值。从您的评论中猜测,您需要类别和category_id匹配的另一个表中相关行的计数。以下是此类SQL查询的示例:

    $db->pquery("SELECT c.`category_id`, c.`category_name`, COUNT(*) AS `count`
    FROM `database_categorys` AS c 
    LEFT OUTER JOIN `other_table` AS t ON t.category_id = c.category_id
    GROUP BY c.category_id
    ORDER BY c.`category_name` ASC");
    

联接是SQL的基本组成部分。如果您尝试使用SQL而不学习使用连接,这就像使用PHP而不学习使用while循环。

从这里开始:A Visual Explanation of SQL Joins

答案 1 :(得分:0)

在第一个查询的while loop or fetching of records完成后尝试执行第二个查询。

修改

您需要使用JOIN,或使用IN合并2个查询。这是manual