CakeFest 2024: The Official CakePHP Conference

PDOStatement::closeCursor

(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.9.0)

PDOStatement::closeCursor Закрывает курсор, переводя запрос в состояние готовности к повторному запуску

Описание

public PDOStatement::closeCursor(): bool

PDOStatement::closeCursor() освобождает соединение с сервером, давая возможность запускать другие SQL-запросы. Метод оставляет запрос в состоянии готовности к повторному запуску.

Этот метод полезен при использовании драйверов баз данных, которые не позволяют запустить PDOStatement, пока предыдущий объект PDOStatement не выберет все данные из результирующего набора. Если это ограничение распространяется на ваш драйвер, будет вызвана ошибка нарушения последовательности запросов (out-of-sequence error).

PDOStatement::closeCursor() может быть реализован как дополнительный метод конкретного драйвера (позволяющий добиться максимальной эффективности работы), либо как внутренний метод PDO, если такой функции в драйвере нет. Реализация внутреннего метода PDO семантически схожа с приведённой ниже:

<?php
do {
while (
$stmt->fetch())
;
if (!
$stmt->nextRowset())
break;
} while (
true);
?>

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Возвращает true в случае успешного выполнения или false, если возникла ошибка.

Ошибки

Выдаёт ошибку уровня E_WARNING, если атрибуту PDO::ATTR_ERRMODE установлено значение PDO::ERRMODE_WARNING.

Выбрасывает исключение PDOException, если атрибуту PDO::ATTR_ERRMODE установлено значение PDO::ERRMODE_EXCEPTION.

Примеры

Пример #1 Пример использования PDOStatement::closeCursor()

В приведённом примере, объект PDOStatement $stmt возвращает несколько строк, однако приложение считывает только первую из них, оставляя объект PDOStatement в состоянии, когда есть ещё невыбранные строки. Чтобы быть уверенным в том, что приложение будет работать со всеми драйверами баз данных, автор добавил вызов метода PDOStatement::closeCursor() объекта $stmt перед тем как запустить другой запрос PDOStatement $otherStmt.

<?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();
?>

Смотрите также

add a note

User Contributed Notes 4 notes

up
2
Anonymous
8 years ago
In case this is helpful to anybody else who ends-up here after getting the following error:

SQLState: 24000 [Microsoft][ODBC SQL Server Driver]Invalid cursor state

PDOStatement :: closeCursor() did not fix the issue for me. However, adding SET NOCOUNT ON to the beginning of my stored procedure did.
up
-7
jhill9693 at gmail dot com
12 years ago
If you ran a SQL statement (vs a query that returns data) such as UPDATE, try unsetting your PDOStatement object instead of calling PDOStatement::closeCursor().
up
-9
Anonymous
8 years ago
At least with MySQL this function also resets any bound columns, so the fetches will go through as expected but you will be getting stale data in the loop.

Redo all the binds before continuing!
up
-12
narada dot sage at googlemail dot com
17 years ago
When running multiple queries one after another especially when stored procedures are involved one must release all result sets and fetch all rows in each result set for a stored procedure before moving onto the next query. This is important because a stored procedure returns an extra (empty) result set as a result of having called the procedure itself.

In my case calling PDOStatement :: closeCursor() did not work (on php-5.1.3-rc2) and I was presented with the following error message: "SQLSTATE[HY000]: General error: 2013 Lost connection to MySQL server during query" upon trying to PDO :: prepare() my second query. So I used the following drop in replacement within one of my classes which fixed the issue.

<?php
/**
* @param PDOStatement $oStm
*/
public static function closeCursor($oStm) {
do
$oStm->fetchAll();
while (
$oStm->nextRowSet());
}
?>
To Top