为什么 UPDATE 准备好的语句上的 PDO::fetchAll() 会导致“未缓冲的查询处于活动状态”异常?

Dav*_*oua 0 php mysql pdo

PHP 版本PHP 7.4.13

我遇到了这个问题,fetchAll()在一个准备好的语句上调用了一个UPDATE查询:

$stmt    = $db->prepare( "UPDATE `table` SET value = value + ? WHERE id = ?" );
$success = $stmt->execute( $arguments );

$result  = $stmt->fetchAll( PDO::FETCH_ASSOC );  // ? This causes the exception
Run Code Online (Sandbox Code Playgroud)

在研究MySQL error 2014 Cannot execute queries while other unbuffered queries are active异常的原因时,这里提出的其他问题似乎没有涵盖这种情况。

为什么会$stmt->fetchAll()在一个UPDATE查询原因下列异常情况发生?

PHP Fatal error:  Uncaught PDOException: SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active.  Consider using PDOStatement::fetchAll().  Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. 
Run Code Online (Sandbox Code Playgroud)

具体来说,我想知道在这种情况下指的是什么“其他未缓冲的查询处于活动状态”。

(我知道这没有意义,它是无效的应该这样做,但我在这里问的是为什么会导致该异常,特别是“无缓冲”查询处于活动状态。)


nb – 设置MYSQL_ATTR_USE_BUFFERED_QUERYtrue不会影响我在这里问的内容。

Dha*_*man 5

通常,尝试从 UPDATE/INSERT 语句获取结果集是无效操作。MySQL 没有返回结果,因此没有什么可获取的。

您看到的异常是作为回归错误出现的,因为我们修复了许多其他错误。其中之一导致在没有结果集但您尝试获取它时出现异常。这是一个不同步的错误。

但是,考虑到数据库抽象库中的常见用法是始终获取结果集并且错误消息非常混乱,我们决定在 PDO 中隐藏错误消息。现在,如果您尝试从语句中获取数据,PDO 将在内部检查是否有结果,如果没有,它将返回一个空数组/null。

此错误仅存在于 PHP 7.4.13/8.0.0 中。它已在 7.4.14 中修复。