您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

MySQL 错误 2014 的原因无法执行查询而其他无缓冲查询处于活动状态

MySQL 错误 2014 的原因无法执行查询而其他无缓冲查询处于活动状态

MysqL 客户端协议不允许多个查询“进行中”。也就是说,您已经执行了一个查询并且您已经获取了一些结果,但不是全部——然后您尝试执行第二个查询。如果第一个查询仍有要返回的行,则第二个查询会出错。

客户端库通过在第一次获取时隐式获取一个查询所有行来解决这个问题,然后后续获取简单地迭代内部缓存的结果。这使他们有机会关闭游标(就 MysqL 服务器而言)。这就是“缓冲查询”。这与使用 fetchAll() 的工作原理相同,因为这两种情况都必须在 PHP 客户端中分配足够的内存来保存完整的结果集。

不同之处在于缓冲查询将结果保存在 MysqL 客户端库中,因此 PHP 无法访问行,直到您按顺序 fetch() 每一行。而 fetchAll() 会立即为所有结果填充一个 PHP 数组,允许您访问任何随机行。

使用 fetchAll() 的主要原因是结果可能太大而不适合您的 PHP memory_limit。但看起来您的查询结果无论如何都只有一行,所以这应该不是问题。

获取最后一行之前,您可以使用 closeCursor() 来“放弃”结果。MysqL 服务器得到通知,它可以在服务器端丢弃该结果,然后您可以执行另一个查询。在完成获取给定的结果集之前,您不应关闭光标()。

另外:我注意到你在循环内一遍又一遍地执行你的 $stmt2 ,但它每次都会返回相同的结果。根据将循环不变代码移出循环的原则,您应该在开始循环之前执行一次,并将结果保存在 PHP 变量中。因此,无论使用缓冲查询还是 fetchAll(),您都无需嵌套查询

所以我建议你这样写你的代码

$sql ='SELECT temp_id FROM temp1';
$stmt2 = db::db()->prepare($sql);
$stmt2->execute();
$rs2 = $stmt2->fetchAll(PDO::FETCH_ASSOC);
$stmt2->closeCursor();

$sql='SELECT COUNT(*) AS valid FROM cities_has_zipcodes 
      WHERE cities_id=:cities_id AND zipcodes_id=:zipcodes_id';
$stmt1 = db::db()->prepare($sql);

foreach($data AS $row)
{
    try
    {
        $stmt1->execute($row);
        $rs1 = $stmt1->fetchAll(PDO::FETCH_ASSOC);
        $stmt1->closeCursor();
        syslog(LOG_INFO,'$rs1: '.print_r($rs1[0],1).' '.rand());
        syslog(LOG_INFO,'$rs2: '.print_r($rs2[0],1).' '.rand());
    }
    catch(PDOException $e){echo(sql_error($e));}            
}

注意我还使用了命名参数而不是位置参数,这使得将 $row 作为参数值数组传递更简单。如果数组的键与参数名称匹配,则只需传递数组即可。在旧版本的 PHP 中,您必须:在数组键中包含前缀,但您不再需要它了。

无论如何你应该使用MysqLnd。它具有更多功能,更节省内存,并且其许可证与 PHP 兼容。

MySQL 2022/1/1 18:53:23 有411人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶