31.6. Получение результатов запроса частями#
31.6. Получение результатов запроса частями #
Обычно libpq собирает весь результат SQL-команды и возвращает его приложению в виде одного PGresult
. Это может быть неприемлемо для команд, которые возвращают большое количество строк. В таких случаях приложения могут использовать PQsendQuery
и PQgetResult
в режиме одной строки или режиме пакетной обработки. В этих режимах строки результата возвращаются приложению по мере их получения от сервера, по одной за раз в режиме одной строки или группами в режиме пакетной обработки.
Чтобы войти в один из этих режимов, вызовите PQsetSingleRowMode
или PQsetChunkedRowsMode
сразу после успешного вызова PQsendQuery
(или аналогичной функции). Этот выбор режима действует только для
текущего выполняемого запроса. Затем вызывайте PQgetResult
многократно, пока он не вернет null, как описано в Раздел 31.4. Если запрос возвращает какие-либо строки, они возвращаются
в виде одного или нескольких объектов PGresult
, которые выглядят как
обычные результаты запроса, за исключением того, что имеют код состояния
PGRES_SINGLE_TUPLE
для режима одной строки или
PGRES_TUPLES_CHUNK
для режима фрагментов, вместо
PGRES_TUPLES_OK
. В каждом объекте PGRES_SINGLE_TUPLE
содержится ровно одна строка результата, в то время как
объект PGRES_TUPLES_CHUNK
содержит как минимум одну
строку, но не более указанного количества строк на фрагмент.
После последней строки, или сразу, если
запрос возвращает ноль строк, возвращается объект с нулем строк и статусом
PGRES_TUPLES_OK
; это сигнал о том, что больше строк не будет. (Но обратите внимание, что все равно необходимо продолжать
вызывать PQgetResult
до тех пор, пока он не вернет null.) Все эти
объекты PGresult
будут содержать те же данные описания строк (имена столбцов, типы и т.д.), которые имел бы обычный
объект PGresult
для запроса.
Каждый объект должен быть освобожден с помощью PQclear
как обычно.
При использовании режима конвейера необходимо активировать режим одиночной строки или фрагментированный режим для каждого запроса в конвейере перед получением результатов для этого запроса с помощью PQgetResult
. См. Раздел 31.5 для получения дополнительной информации.
PQsetSingleRowMode
#Выберите режим одиночной строки для текущего выполняющегося запроса.
int PQsetSingleRowMode(PGconn *conn);
Эта функция может быть вызвана только непосредственно после
PQsendQuery
или одной из его сопутствующих функций, перед любой другой операцией с соединением, такой какPQconsumeInput
илиPQgetResult
. Если вызвана в правильное время, функция активирует режим одной строки для текущего запроса и возвращает 1. В противном случае режим остается неизменным, и функция возвращает 0. В любом случае режим возвращается к нормальному после завершения текущего запроса.PQsetChunkedRowsMode
#Выберите режим с разбиением на части для текущего выполняемого запроса.
int PQsetChunkedRowsMode(PGconn *conn, int chunkSize);
Эта функция аналогична
PQsetSingleRowMode
, за исключением того, что она указывает извлечение доchunkSize
строк заPGresult
, не обязательно только одной строки. Эта функция может быть вызвана только сразу послеPQsendQuery
или одной из ее родственных функций, до любой другой операции с соединением, такой какPQconsumeInput
илиPQgetResult
. Если вызвана в нужное время, функция активирует режим пакетной обработки для текущего запроса и возвращает 1. В противном случае режим остается неизменным, и функция возвращает 0. В любом случае, режим возвращается к нормальному после завершения текущего запроса.
Предостережение
При обработке запроса сервер может вернуть несколько строк, а затем столкнуться с ошибкой, что приведет к прерыванию запроса. Обычно, libpq отбрасывает такие строки и сообщает только об ошибке. Однако в режиме одной строки или пакетном режиме некоторые строки могут быть уже возвращены приложению. Следовательно, приложение увидит некоторые объекты PGRES_SINGLE_TUPLE
или PGRES_TUPLES_CHUNK
PGresult
, за которыми следует объект PGRES_FATAL_ERROR
. Для правильного транзакционного поведения приложение должно быть спроектировано таким образом, чтобы отбрасывать или отменять все, что было сделано с ранее обработанными строками, если запрос в конечном итоге завершится неудачей.