因此,如果我运行这样的查询,那么我正在使用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();
}
答案 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
循环。
答案 1 :(得分:0)