【发布时间】:2014-10-23 05:11:23
【问题描述】:
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 上 MySQL 5.6.16 版的错误,我将不胜感激。更重要的是,我希望有一个解决方法。谢谢。
【问题讨论】:
-
mysqli"can" (as I recall) 在结果集之间切换,但需要将整个应用程序移动到另一个数据库交互层。 -
为什么不能将所有这些字符串作为 4 个单独的查询运行?
-
@silkfire 我已经更新了我的问题以添加重要的细节(很抱歉,当我第一次发布问题时没有这样做)。现在的代码与我运行的代码 100% 相同。事实上,SQL 是嵌入在存储过程中的。对于我的实际应用,查询要复杂得多,而且不容易重构。
-
@DanNissenbaum 实际上,我只是在我的 WAMP 安装中使用 MySQL 5.6.17 尝试了您的代码,只要我使用
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);启用模拟准备,它就可以出色地工作。