首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PDO::query()遇到“当其他未缓冲的查询处于活动状态时不能执行查询”。

问PDO::query()遇到“当其他未缓冲的查询处于活动状态时不能执行查询”。
EN

Stack Overflow用户
提问于 2015-01-21 12:06:12
回答 4查看 7.4K关注 0票数 8

梅比其他人也有和我一样的问题。我犯了一个错误:

当其他未缓冲的查询处于活动状态时,无法执行查询。考虑使用PDOStatement::fetchAll()。或者,如果您的代码只对mysql运行,则可以通过设置PDO::MYSQL_ATTR_USE_BUFFERED_QUERY属性启用查询缓冲。

关于PDO。正如许多线程所提到的,错误可能至少是以下问题之一:

  1. 查询游标没有像这里提到的那样用closeCursor()关闭;在其他未缓冲查询处于活动状态时,MySQL错误2014的原因无法执行查询
  2. 有两个以上的查询,其中有一个语句,如下所述:当其他未缓冲的查询处于活动状态时,PDO无法执行查询。
  3. 这里提到的mysql驱动程序中的一个bug:当其他未缓冲的查询处于活动状态时,是什么导致PDO错误不能执行查询?

就我而言,上述一切都没有帮助,我花了一段时间才解决了这个问题。这是我的代码(伪代码):

代码语言:javascript
复制
$stmt->startTransaction();
$stmt = db::getInstance()->prepare("CALL phones(:phone)");
$stmt->prepare('SELECT * FROM database');
$stmt->execute();
$aData = $stmt->fetchAll();
$stmt->closeCursor();

$stmt->query("USE sometable;");

在我把它改成:

代码语言:javascript
复制
$stmt->startTransaction();
$stmt = db::getInstance()->prepare("CALL phones(:phone)");
$stmt->prepare('SELECT * FROM database');
$stmt->execute();
$aData = $stmt->fetchAll();
$stmt->closeCursor();

$stmt->exec("USE sometable;");

对我来说很管用。查询和执行有什么区别?

代码语言:javascript
复制
PDO::exec() - "Execute an SQL statement and return the number of affected rows"
PDO::query() - "Executes an SQL statement, returning a result set as a PDOStatement object"

为什么在这种情况下PDO::query()不能工作?当调用游标时,光标将关闭。

EN

回答 4

Stack Overflow用户

发布于 2015-01-21 12:19:21

虽然可以想象,您在这里遇到了mysql驱动程序错误,但我们不能肯定这一点,因为您没有给我们这些信息(您使用的是什么版本的PHP?它使用mysqlnd =>检查php -i | grep mysqlnd吗?剩下的代码是什么样子的?)。

对你的问题还有许多其他可能的解释。我怀疑问题实际上是您未能关闭所有游标和/或获取所有结果,因为$stmt被大量重用。

直接引用于PDO::query 手册页

如果在发出对PDO::query()的下一次调用之前,不提取结果集中的所有数据,则调用可能失败。调用PDOStatement::closeCursor(),在发出下一次对PDO::query()的调用之前释放与PDOStatement对象关联的数据库资源。

您可以在closeCursor上调用$stmt,这是正确的,但您并没有关闭您创建的所有游标:

代码语言:javascript
复制
//<-- what is $stmt here?
$stmt->startTransaction();
//no matter, you've reassigned it a PDOStatement instance
$stmt = db::getInstance()->prepare("CALL phones(:phone)");
//Huh? You're preparing yet another query on an instance of PDOStatement?
$stmt->prepare('SELECT * FROM database');
//you're executing this one, though
$stmt->execute();
//and fetching all data
$aData = $stmt->fetchAll();
//and closing this last statement
$stmt->closeCursor();

但是,您分配给$stmt (存储过程调用)的第一条语句呢?光标在任何地方都没有关闭

现在来看一下PDO::query和PDO::exec之间的主要区别。再次引用手册:

PDO::exec()不返回SELECT语句的结果。

鉴于:

PDO::query()在一个函数调用中执行一个SQL语句,返回语句作为PDOStatement对象返回的结果集(如果有的话)。

票数 5
EN

Stack Overflow用户

发布于 2018-04-13 12:27:22

我也遇到了这个问题。很可能是个虫子。如果我们使用以下代码,那么您将看到消息'General error: 2014不能在其他未缓冲查询处于活动状态时执行查询‘时,它是如何失败的。

代码语言:javascript
复制
$pdo = new \PDO("mysql:host=localhost", "root", "");
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);

$pdo->query("USE test");

如果您将$pdo->query("USE test");更改为$pdo->exec("USE test");,它将工作。如果您将$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);更改为$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);,它也会工作。不过,我还没有找到合适的解决办法。

票数 4
EN

Stack Overflow用户

发布于 2020-08-09 14:32:56

我用以下步骤来解决这个问题:

执行后:$stmt = db::getInstance()->prepare("CALL phone(:phone)“);

我关闭:$stmt->startTransaction();

然后,我再次打开事务来使用下面的查询:$stmt-> FROM (‘SELECT*FROM database');

我的解决方案是:一条语句调用过程"CALL phone(:phone)“,另一条语句用于执行查询wtih "SELECT * FROM database”。

就是这样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28066842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档