PDO“Uncaught exception'PDOException'..当其他未缓冲的查询处于活动状态时,无法执行查询。考虑使用PDOStatement :: fetchAll()。“

时间:2012-07-15 14:18:06

标签: php mysql exception pdo

我知道这个问题已被多次询问,但我已经阅读了许多问题的答案,但仍然无法理解为什么我会收到此错误:

  

致命错误:未捕获的异常' PDOException'与消息   ' SQLSTATE [HY000]:常规错误:2014无法执行查询   其他未缓冲的查询处于活动状态。考虑使用   PDOStatement对象::使用fetchall()。或者,如果您的代码只是永远   要对mysql运行,您可以通过设置启用查询缓冲   PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY属性。'

第一件事很奇怪,就是我在我的localhost(wampserver)上没有出错,但我确实在我的网络服务器上得到了它。我的localhost上的php版本是5.3.10,而我的web服务器上的php版本是5.3.13。

我已经读过,当前一个查询中的数据留在缓冲区中时,此错误的来源正在进行查询。对我来说情况并非如此 - 我已经回复了所有数据,并且我知道查询中返回的每一行都被提取。

话虽如此,我发现将我的一个查询更改为fetchAll而不是fetch可以解决问题,但是因为我知道正在读取返回的所有行。当我使用fetchAll进行查询(它是在循环中进行)时,我在每个循环中打印出数组,并且循环中的每个查询只有一个项目在数组中。

还有一条信息。它不是我更改为fetchAll的查询(这使得错误消失)抛出PDO错误,稍后在我的php文件中有另一个查询抛出错误。我的文件基本上是这样的:

... code ...

query 1

... code ...

loop
query 2
end loop

... code ... 

query 3

如果我注释掉查询3,则没有错误。如果我注释掉,或更改为fetchAll,查询2,则没有错误。查询1没有任何影响。

我还想补充一点,我已尝试在页面上(同时)将LIMIT 1添加到所有查询中,但错误仍然存​​在。我认为这证明缓冲区中没有未读数据,对吧?

我真的很困惑,所以我很感激你的建议。在有人要求之前,我无法发布完整代码,但这是我的代码的简化版本:

$stmt = $this->db->prepare('SELECT ... :par LIMIT 1');
makeQuery($stmt, array(':par' => $var));
$row = $stmt->fetch(PDO::FETCH_ASSOC);


$stmt = $this->db->prepare('SELECT ... :par LIMIT 1');

for loop
    makeQuery($stmt, array(':par' => $var));
    $row2 = $stmt->fetch(PDO::FETCH_ASSOC);
    ... [use row2] ...
end for loop


$stmt = $this->db->prepare('SELECT ... :par LIMIT 1');
makeQuery($stmt, array(':par' => $var));
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);

以下是makeQuery()

/**************************************************************************************************************
* Function: makeQuery                                                                                         *
* Desc: Makes a PDO query.                                                                                    *
* Pre conditions: The statement/query and an array of named parameters (may be empty) must be passed.         *
* Post conditions: The PDO query is executed. Exceptions are caught, displayed, and page execution stopped.   *
**************************************************************************************************************/
function makeQuery($stmt, $array, $errMsg = '')
{
    try 
    {
        $stmt->execute($array);
    }
    catch (PDOException $e) 
    {
        print $errMsg != ''?$errMsg:"Error!: " . $e->getMessage() . "<br/>";
        die();
    }
}

感谢您的帮助!

编辑:我也尝试在查询2之后执行以下操作(因为这似乎是问题的根源:

$row2 = $stmt->fetch(PDO::FETCH_ASSOC); var_dump($row2);

输出结果为:

bool(false) 

我偶然发现了一个PDO错误吗?

3 个答案:

答案 0 :(得分:2)

您需要获取,直到行获取尝试失败。我知道你可能只在结果集中有一行,并认为一次获取​​就足够了,但不是。

你可能还有其他的陈述,你没有完全“获取,直到获取失败”。是的,我看到你提取,直到一个语句的提取失败。

另见closecursor()

$sql = "select * from test.a limit 1";
$stmt = $dbh->prepare($sql);
$stmt->execute(array());
$row = $stmt->fetch();
$stmt->closeCursor();

$sql = "select * from test.a limit 1";
$stmt = $dbh->prepare($sql);
$stmt->execute(array());
list($row) = $stmt->fetchAll(); //tricky

答案 1 :(得分:2)

经过几天的努力,我终于发现这对我有用了:

$db = new PDO ($cnstring, $user, $pwd);
$db->setAttribute (PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

答案 2 :(得分:0)

如果您尝试获取非 SELECT 查询(例如 - UPDATE/INSERT/ALTER/CREATE),也会发生这种情况。确保仅对 SELECT 查询使用 fetch 或 fetchAll。

Possible Duplicate Answer/Question