2

所以我在使用 PDO MySQL 时遇到的一个问题是,如果我运行这样的查询:

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

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

这是我的 pquery 顺便说一句:

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

    $this->counter++;

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

还有我的 fetch 功能:

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

2 回答 2

4

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

您有以下选择:

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

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

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

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

    但这也涉及到 N+1 Selects 反模式。

  • 最好编写一个 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循环一样。

从这里开始: SQL 连接的可视化解释

于 2012-11-02T20:28:32.273 回答
0

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

编辑:

您需要使用JOIN它,或者使用IN. 这是手册

于 2012-11-02T20:05:09.863 回答