Php PDO::query()运行到";当其他未缓冲查询处于活动状态时,无法执行查询。”;

Php PDO::query()运行到";当其他未缓冲查询处于活动状态时,无法执行查询。”;,php,mysql,pdo,unbuffered-queries,Php,Mysql,Pdo,Unbuffered Queries,也许其他人和我有同样的问题。 我遇到了错误: 当其他未缓冲查询处于活动状态时,无法执行查询。 考虑使用pdoCalp::FutAccess()。或者,如果您的代码 只在mysql上运行,您可以启用查询 通过设置PDO::MYSQL\u ATTR\u USE\u BUFFERED\u QUERY属性进行缓冲 在PDO上。正如前面提到的许多线程一样,错误至少可能是以下问题之一: 查询游标未使用此处提到的closeCursor()关闭 有两个以上的查询,其中一个语句如下所述: mysql驱动程序中的一

也许其他人和我有同样的问题。 我遇到了错误:

当其他未缓冲查询处于活动状态时,无法执行查询。 考虑使用pdoCalp::FutAccess()。或者,如果您的代码 只在mysql上运行,您可以启用查询 通过设置PDO::MYSQL\u ATTR\u USE\u BUFFERED\u QUERY属性进行缓冲

在PDO上。正如前面提到的许多线程一样,错误至少可能是以下问题之一:

  • 查询游标未使用此处提到的
    closeCursor()
    关闭
  • 有两个以上的查询,其中一个语句如下所述:
  • mysql驱动程序中的一个错误,如下所述:
  • 在我的情况下,所有这些都没有帮助,我花了一些时间才解决问题。这是我的代码(伪代码):

    我把它改成:

    $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;");
    
    这对我的工作有帮助。query和exec之间有什么区别

    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()不起作用?光标在调用时是关闭的。

    虽然您可能确实在这里遇到了mysql驱动程序错误,但我们不能确定这一点,因为您没有向我们提供该信息(您使用的是什么版本的PHP?它是否使用
    mysqlnd
    =>检查
    PHP-i | grep mysqlnd
    ?您的其余代码是什么样子的?。
    您的问题还有许多其他可能的解释。我怀疑问题实际上是您未能关闭所有游标和/或获取所有结果,因为
    $stmt
    被大量重用:

    直接引用自
    PDO::query

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

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

    //<-- 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();
    
    //startTransaction();
    //不管怎样,您已经将其重新指定为PDO语句实例
    $stmt=db::getInstance()->prepare(“呼叫电话(:电话)”;
    //哈?你在准备另一个关于PDO语句实例的查询?
    $stmt->prepare('SELECT*FROM database');
    //不过,你正在执行这个
    $stmt->execute();
    //以及获取所有数据
    $aData=$stmt->fetchAll();
    //结束这最后一句话
    $stmt->closeCursor();
    
    但是,您分配给
    $stmt
    (存储过程调用)的第一条语句呢?光标不会在任何地方关闭

    现在了解
    PDO::query
    PDO::exec
    之间的主要区别。再次引用手册:

    PDO::exec()
    不会从SELECT语句返回结果

    鉴于:

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


    我也遇到过这个问题。它很可能是一个bug。如果我们使用下面的代码,那么您将看到它如何在消息“一般错误:2014不能执行查询,而其他未缓冲查询是激活的情况下失败。请考虑使用pdoCalp::FETAccess()。


    如果您将
    $pdo->query(“USE test”);
    更改为
    $pdo->exec(“USE test”);
    它将工作。如果您将
    $pdo->setAttribute(\pdo::ATTR\u EMULATE\u PREPARES,false);
    更改为
    $pdo->setAttribute(\pdo::ATTR\u EMULATE\u PREPARES,true)
    它也会起作用。不过我还没有找到合适的解决方案。

    我通过以下步骤解决了这个问题:

    执行后: $stmt=db::getInstance()->prepare(“呼叫电话(:电话)”

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

    然后,我再次打开事务以使用以下查询: $stmt->prepare('SELECT*FROM database')

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


    就是这样。

    小心,如果您试图获取非选择查询(例如-UPDATE/INSERT/ALTER/CREATE),也可能发生这种情况。

    调用光标时,光标已关闭
    //<-- 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();
    
    $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");