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