如果这对在遇到以下错误后最终来到这里的任何人有帮助
SQLState: 24000 [Microsoft][ODBC SQL Server Driver]Invalid cursor state
PDOStatement :: closeCursor() 并没有解决我的问题。但是,在存储过程的开头添加 SET NOCOUNT ON 解决了这个问题。
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.9.0)
PDOStatement::closeCursor — 关闭游标,使语句能够再次执行
PDOStatement::closeCursor() 释放与服务器的连接,以便可以发出其他 SQL 语句,但将语句保留在能够再次执行的状态。
此方法对于不支持在先前执行的 PDOStatement 对象仍有未提取的行时执行 PDOStatement 对象的数据库驱动程序很有用。如果您的数据库驱动程序存在此限制,则问题可能会表现为顺序错误。
PDOStatement::closeCursor() 作为可选的驱动程序特定方法(允许最大效率)或作为没有安装驱动程序特定函数时的通用 PDO 回退来实现。PDO 通用回退在语义上与在 PHP 脚本中编写以下代码相同
<?php
do {
while ($stmt->fetch())
;
if (!$stmt->nextRowset())
break;
} while (true);
?>
此函数没有参数。
如果属性 PDO::ATTR_ERRMODE
设置为 PDO::ERRMODE_WARNING
,则发出级别为 E_WARNING
的错误。
如果属性 PDO::ATTR_ERRMODE
设置为 PDO::ERRMODE_EXCEPTION
,则抛出 PDOException。
示例 #1 PDOStatement::closeCursor() 示例
在以下示例中,$stmt PDOStatement 对象返回多行,但应用程序仅提取第一行,从而使 PDOStatement 对象处于具有未提取行的状态。为了确保应用程序能够与所有数据库驱动程序一起使用,作者在执行 $otherStmt PDOStatement 对象之前,在 $stmt 上插入对 PDOStatement::closeCursor() 的调用。
<?php
/* 创建一个 PDOStatement 对象 */
$stmt = $dbh->prepare('SELECT foo FROM bar');
/* 创建第二个 PDOStatement 对象 */
$otherStmt = $dbh->prepare('SELECT foobaz FROM foobar');
/* 执行第一个语句 */
$stmt->execute();
/* 从结果中仅提取第一行 */
$stmt->fetch();
/* 以下对 closeCursor() 的调用可能需要某些驱动程序 */
$stmt->closeCursor();
/* 现在我们可以执行第二个语句 */
$otherStmt->execute();
?>