This question without an accepted answer引发了MySQL的灾难性问题,我在Windows上以修改后的形式在MySQL版本5.6.16上遇到了这个问题。
问题很容易重现:我在这里包含它(从上面链接的问题中复制,但是对我的代码进行了更改):
$pdo = /* connection stuff here */
$sql = "call test();"; // call stored procedure - see below
$statement = $connection->query($sql);
do {
$rowset = $statement->fetchAll(PDO::FETCH_ASSOC);
if($rowset) {
// Do stuff with $rowset
}
} while($statement->nextRowset());
以下是存储过程test
的定义:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`$$
CREATE PROCEDURE `test`()
BEGIN
SELECT 1; SELECT 2; SELECT 3; SELECT 4;
END$$
DELIMITER ;
我的代码和上面链接的代码之间的唯一区别是我将SQL查询打包到存储过程中。
就我而言,while
语句返回true
四次,而不是三次(应该只有三次)。第四次之后,fetchAll(...)
会引发SQLSTATE[HY000]: General error
错误。
不幸的是,这个问题是灾难性的。除了使用nextRowSet()
函数之外,PDO没有其他方法可以迭代到以下行集。因此,为了解决这个问题,我可能会恢复到以前版本的MySQL。
我找到了两个似乎表明此问题的链接,如下所示: https://bugs.php.net/bug.php?id=67130和 http://permalink.gmane.org/gmane.comp.php.devel/81518
我希望确认这确实是Windows上版本5.6.16的MySQL的错误。更重要的是,我希望得到一个解决方法。感谢。
答案 0 :(得分:2)
我遇到了与PDO :: nextRowset()相同的问题,因为即使没有更多的行集可用,它也会返回true,因此在调用fetchAll()时会引发异常HY000。 (在PHP 5.5.12 windows上测试,Mysql 5.5.17 linux)
此问题的解决方法是在获取行集之前使用方法PDO :: columnCount()检查列数。如果它不为零,则表示您有一个有效的行集,因此可以调用PDO :: fetchAll()。
即使PDO :: nextRowset()报告为true,columnCount()也会在移动到下一行集之前报告列数。
示例:
while ($objQuery->columnCount()) {
$tab[] = $objQuery->fetchAll(\PDO::FETCH_ASSOC);
$objQuery->nextRowset();
}
答案 1 :(得分:-1)
如果问题是由多个结果集引起的,那么最好的解决办法就是找到在单个查询中避免多个结果集的方法。
例如,如果预期的结果是相同的格式(我希望它们可能是因为您打算使用相同的代码来处理所有这些),那么您可能会使用UNION将四个查询组合在一起。
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4;
如果失败,您可以为每个SELECT执行单独的查询,并将结果移交给函数进行处理。