Функции для выполнения команд

После успешной установки соединения с сервером баз данных функции, описанные в этом разделе, используются для выполнения запросов и команд SQL.



Основные функции

PQexec

Передает команду серверу и ожидает результата.

PGresult *PQexec(PGconn *conn, const char *command);

Возвращает указатель на PGresult или, возможно, пустой указатель. Обычно возвращается непустой указатель, за исключением ситуаций нехватки памяти или серьезных ошибок, например невозможности отправить команду серверу. Для проверки возвращаемого значения на ошибки нужно вызвать функцию PQresultStatus (в т. ч. в случае пустого указателя — тогда она возвратит PGRES_FATAL_ERROR). Для получения дополнительной информации о таких ошибках воспользуйтесь функцией PQerrorMessage.

Командная строка может включать в себя несколько команд SQL (разделяемых точкой с запятой). Несколько запросов, отправленных в одном вызове PQexec, обрабатываются в рамках одной транзакции, если только в строку запроса не включены явно команды BEGIN/COMMIT, чтобы разделить его на несколько транзакций. (Подробную информацию о том, как сервер обрабатывает строки с несколькими операторами, см. в подразделе Несколько операторов в простом запросе.) Однако обратите внимание, что возвращаемая структура PGresult описывает только результат последней команды, выполненной из этой строки. Если одна из команд завершится сбоем, обработка строки на этом останавливается, и возвращаемая PGresult описывает состояние ошибки.

PQexecParams

Передает команду серверу и ожидает результата, имея при этом возможность передавать параметры отдельно от текста команды SQL.

PGresult *PQexecParams(PGconn *conn,
                       const char *command,
                       int nParams,
                       const Oid *paramTypes,
                       const char * const *paramValues,
                       const int *paramLengths,
                       const int *paramFormats,
                       int resultFormat);

Функция PQexecParams похожа на функцию PQexec, но предлагает дополнительную функциональность: значения параметров могут быть указаны отдельно от собственно командной строки, а результаты запроса могут быть запрошены либо в текстовом, либо в двоичном формате.

Эта функция имеет следующие аргументы:

  • conn
    Объект, описывающий соединение, через которое передается команда.

  • command
    Строка выполняемой команды SQL. Если используются параметры, то в командной строке на них ссылаются как на $1, $2 и т. д.

  • nParams
    Количество предоставляемых параметров; оно равно длине массивов paramTypes[], paramValues[], paramLengths[] и paramFormats[]. (Указатели на массивы могут равняться NULL, когда nParams равен нулю.)

  • paramTypes[]
    Задает, посредством OID, типы данных, которые должны быть назначены символам параметров. Если paramTypes имеет значение NULL или какой-либо отдельный элемент в этом массиве равен нулю, сервер логически выводит тип данных для символа параметра таким же образом, как сделал бы это для нетипизированной литеральной строки.

  • paramValues[]
    Задает фактические значения параметров. Пустой указатель в этом массиве означает, что соответствующий параметр имеет значение NULL; в противном случае указатель указывает на текстовую строку, завершающуюся нулем (для текстового формата), или двоичные данные в формате, ожидаемом сервером (для двоичного формата).

  • paramLengths[]
    Задает фактические длины данных параметров в двоичном формате. Он игнорируется для параметров со значением NULL и параметров в текстовом формате. Указатель на массив может быть пустым, если двоичные параметры отсутствуют.

  • paramFormats[]
    Определяет, являются ли параметры текстовыми (поместите ноль в запись массива для соответствующего параметра) или двоичными (поместите единицу в запись массива для соответствующего параметра). Если указатель на массив является пустым, предполагается, что все параметры являются текстовыми строками.
    Значения, переданные в двоичном формате, требуют знания внутреннего представления, ожидаемого сервером. Например, целые числа должны передаваться в сетевом порядке байтов. Передача значений numeric требует знания формата, в котором их хранит сервер.

  • resultFormat
    Задает ноль для получения результатов в текстовом формате или один для получения результатов в двоичном формате. (В настоящий момент нет возможности получить различные столбцы результата в разных форматах, хотя это возможно в нижележащем протоколе.)

Главное преимущество функции PQexecParams перед функцией PQexec заключается в возможности отделить значения параметров от командной строки, тем самым избегая необходимости применять трудоемкое и чреватое ошибками экранирование кавычками и управляющими символами.

В отличие от PQexec, PQexecParams позволяет включать в заданную строку не более одной команды SQL. (В ней могут присутствовать точки с запятой, но не более одной непустой команды.) Это ограничение нижележащего протокола, но оно некоторым образом полезно в качестве дополнительной защиты против атак путем внедрения кода SQL.

Совет
Указание типов параметров посредством OID являются трудоемким, особенно если вы предпочитаете не встраивать жестко конкретные значения OID в вашу программу. Однако этого можно избежать даже в случаях, когда сам сервер не может определить тип параметра или выбирает не тот тип, который вы хотите. В тексте команды SQL добавьте к символу параметра явное приведение, чтобы показать, какой тип данных будете передавать. Например:

SELECT * FROM mytable WHERE x = $1::bigint;

Благодаря этому параметр $1 будет восприниматься как имеющий тип bigint, тогда как по умолчанию ему был бы назначен тот же тип, что и у x. Вмешательство в принятие решение о типе параметра либо данным способом, либо путем указания числового OID типа настоятельно рекомендуется при передаче значений параметров в двоичном формате, поскольку двоичный формат имеет меньшую избыточность, чем текстовый, и поэтому куда менее вероятно, что сервер обнаружит ошибку несоответствия типов, допущенную вами.

PQprepare

Отправляет запрос на создание подготовленного оператора с заданными параметрами и ожидает завершения.

PGresult *PQprepare(PGconn *conn,
                    const char *stmtName,
                    const char *query,
                    int nParams,
                    const Oid *paramTypes);

Функция PQprepare создает подготовленный оператор для последующего его выполнения с помощью функции PQexecPrepared. Эта функциональность позволяет командам выполняться многократно без необходимости в повторном синтаксическом анализе и планировании; подробную информацию см. на справочной странице команды PREPARE.

Эта функция создает подготовленный оператор с именем stmtName из строки query, которая должна содержать одну команду SQL. stmtName может быть пустой строкой "" для создания неименованного оператора, и тогда любой уже существующий неименованный оператор автоматически заменяется им; в противном случае, если имя оператора уже определено в текущем сеансе, возникает ошибка. Если используются какие-либо параметры, то в запросе на них них ссылаются как на $1, $2 и т. д. Аргумент nParams — это количество параметров, типы для которых заранее указаны в массиве paramTypes[]. (Указатель на массив может быть равен NULL, когда nParams имеет нулевое значение.) Массив paramTypes[] задает, посредством OID, типы данных, которые должны быть назначены символам параметров. Если paramTypes имеет значение NULL или какой-либо отдельный элемент в этом массиве равен нулю, сервер логически выводит тип данных для символа параметра таким же образом, как сделал бы это для нетипизированной литеральной строки. Кроме того, запрос может использовать символы параметров с номерами большими, чем nParams; для этих символов типы данных тоже будут логически выведены. (Способы определить, какие типы данных были выведены, см. в описании функции PQdescribePrepared.)

Как и у PQexec, результатом обычно является объект PGresult, содержимое которого показывает успех или сбой на стороне сервера. Результат NULL показывает нехватку памяти или невозможность вообще отправить команду. Для получения дополнительной информации о таких ошибках используйте функцию PQerrorMessage.

Подготовленные операторы для использования с функцией PQexecPrepared также можно создать, выполнив операторы SQL PREPARE. Кроме того, хотя функции libpq для удаления подготовленного оператора не существует, для этой цели можно воспользоваться оператором SQL DEALLOCATE.

PQexecPrepared

Отправляет запрос на создание подготовленного оператора с заданными параметрами и ожидает результата.

PGresult *PQexecPrepared(PGconn *conn,
                         const char *stmtName,
                         int nParams,
                         const char * const *paramValues,
                         const int *paramLengths,
                         const int *paramFormats,
                         int resultFormat);

Функция PQexecPrepared похожа на функцию PQexecParams, но выполняемая команда задается путем указания имени ранее подготовленного оператора, а не строки запроса. Эта возможность позволяет командам, которые будут вызываться многократно, подвергаться синтаксическому анализу и планированию всего один раз, а не при каждом их выполнении. Оператор должен быть предварительно подготовлен в рамках текущего сеанса.

Параметры идентичны таковым функции PQexecParams, за исключением того, что вместо строки запроса задается имя подготовленного оператора и отсутствует параметр paramTypes[] (он не нужен, поскольку типы параметров подготовленного оператора были определены при его создании).

PQdescribePrepared

Передает запрос на получение информации о заданном подготовленном операторе и ожидает завершения.

PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);

Функция PQdescribePrepared позволяет приложению получить информацию о ранее подготовленном операторе.

Аргумент stmtName может быть пустой строкой "" или NULL для ссылки на неименованный оператор, в противном случае он должен быть именем существующего подготовленного оператора. При успехе возвращается объект PGresult со статусом PGRES_COMMAND_OK. Для получения информации о параметрах подготовленного оператора к этому PGresult можно применить функции PQnparams и PQparamtype, а функции PQnfields, PQfname, PQftype и т. п. предоставляют информацию о результирующих столбцах этого оператора (если таковые имеются).

PQdescribePortal

Передает запрос на получение информации о заданном портале и ожидает завершения.

PGresult *PQdescribePortal(PGconn *conn, const char *portalName);

Функция PQdescribePortal позволяет приложению получить информацию о ранее созданном портале. (libpq не предоставляет прямого доступа к порталам, но эту функцию можно использовать для просмотра свойств курсора, созданного командой SQL DECLARE CURSOR.)

Аргумент portalName может быть пустой строкой "" или NULL для ссылки на неименованный портал, в противном случае это должно быть имя существующего портала. При успехе возвращается структура PGresult со статусом PGRES_COMMAND_OK. Для получения информации о результирующих столбцах портала (если таковые имеются) к PGresult можно применить функции PQnfields, PQfname, PQftype и т. п.

Структура PGresult содержит результат, возвращенный сервером. Разработчики приложений libpq должны тщательно поддерживать абстракцию PGresult. Для получения доступа к содержимому PGresult следует использовать описанные ниже функции доступа. Избегайте непосредственного обращения к полям структуры PGresult, так как они могут измениться в будущем.

PQresultStatus

Возвращает статус результата команды.

ExecStatusType PQresultStatus(const PGresult *res);

Функция PQresultStatus может вернуть одно из следующих значений:

  • PGRES_EMPTY_QUERY
    Строка, переданная серверу, была пустой.

  • PGRES_COMMAND_OK
    Успешное завершение команды, не возвращающей никаких данных.

  • PGRES_TUPLES_OK
    Успешное завершение команды, возвращающей данные (например, SELECT или SHOW).

  • PGRES_COPY_OUT
    Начался перенос данных Copy Out (с сервера).

  • PGRES_COPY_IN
    Начался перенос данных Copy In (на сервер).

  • PGRES_BAD_RESPONSE
    Ответ сервера не был распознан.

  • PGRES_NONFATAL_ERROR
    Произошла некритическая ошибка (замечание или предупреждение).

  • PGRES_FATAL_ERROR
    Произошла критическая ошибка.

  • PGRES_COPY_BOTH
    Начался перенос данных Copy In/Out (на сервер и с сервера). В настоящий момент эту функциональность используется только для потоковой репликации, так что этот статус не должен появляться в обычных приложениях.

  • PGRES_SINGLE_TUPLE
    PGresult содержит только один кортеж результата, выданного текущей командой. Этот статус появляется, только если для запроса был выбран режим построчного вывода (см. раздел Построчное извлечение результатов запроса).

  • PGRES_PIPELINE_SYNC
    PGresult представляет точку синхронизации в конвейерном режиме, запрошенную функцией PQpipelineSync. Этот статус появляется, только если был выбран конвейерный режим.

  • PGRES_PIPELINE_ABORTED
    PGresult представляет конвейер, получивший ошибку от сервера. Следует многократно вызывать функцию PQgetResult, и каждый раз она будет возвращать этот код состояния до конца текущего конвейера, после чего она вернет PGRES_PIPELINE_SYNC, и сможет возобновиться обычная обработка.

При статусе результата PGRES_TUPLES_OK или PGRES_SINGLE_TUPLE для извлечения строк, возвращенных запросом, можно применить функции, описанные ниже. Обратите внимание, что команда SELECT, которая извлекла ноль строк, все равно показывает PGRES_TUPLES_OK. Статус PGRES_COMMAND_OK предназначен для команд, которые могут никогда не возвращать строк (INSERT или UPDATE без предложения RETURNING и т. п.). Ответ PGRES_EMPTY_QUERY может указывать на ошибку в программном обеспечении клиента.

Результат со статусом PGRES_NONFATAL_ERROR никогда не будет возвращен напрямую PQexec или другими функциями выполнения запросов; вместо этого результаты такого рода передаются обработчику замечаний (см. раздел Обработка замечаний).

PQresStatus

Преобразует значение перечислимого типа, возвращенное функцией PQresultStatus, в строковую константу, описывающую код состояния. Вызывающая функция не должна освобождать память, выделенную под результат.

char *PQresStatus(ExecStatusType status);

PQresultErrorMessage

Возвращает сообщение об ошибке, связанное с командой, или пустую строку, если ошибки не произошло.

char *PQresultErrorMessage(const PGresult *res);

Если произошла ошибка, то возвращенная строка будет включать завершающий символ перевода строки. Вызывающая функция не должна напрямую освобождать память, выделенную под результат. Она будет освобождена, когда связанный маркер PGresult будет передан функции PQclear.

Если сразу после вызова функции PQexec или PQgetResult вызвать функцию PQerrorMessage (для данного соединения), она вернет ту же строку, что и функция PQresultErrorMessage (для данного результата). Однако структура PGresult будет хранить свое сообщение об ошибке, пока не будет уничтожена, тогда как сообщение об ошибке для данного соединения будет изменяться при выполнении последующих операций. Используйте функцию PQresultErrorMessage, когда хотите узнать статус, связанный с конкретным объектом PGresult; используйте функцию PQerrorMessage, когда хотите узнать статус, возвращенный последней операцией на данном соединении.

PQresultVerboseErrorMessage

Возвращает переформатированную версию сообщения об ошибке, связанного с объектом PGresult.

char *PQresultVerboseErrorMessage(const PGresult *res,
                                  PGVerbosity verbosity,
                                  PGContextVisibility show_context);

В некоторых ситуациях клиент может пожелать получить более подробную версию выданного ранее сообщения об ошибке. Функция PQresultVerboseErrorMessage удовлетворяет эту потребность, составляя сообщение, которое было бы выдано функцией PQresultErrorMessage, если бы заданный уровень детализации действовал для соединения на момент генерирования данного PGresult. Если PGresult не является результатом с ошибкой, вместо этого выдается сообщение «PGresult is not an error result». Возвращаемая строка включает завершающий символ перевода строки.

В обличие от большинства других функций, извлекающих данные из PGresult, результатом этой функции является только что размещенная в памяти строка. Когда необходимость в этой строке отпадет, вызывающая функция должна освободить ее с помощью PQfreemem().

При нехватке памяти может быть возвращен NULL.

PQresultErrorField

Возвращает индивидуальное поле отчета об ошибке.

char *PQresultErrorField(const PGresult *res, int fieldcode);

Аргумент fieldcode — это идентификатор поля ошибки; см. символы, перечисленные ниже. Если PGresult не является результатом с ошибкой или предупреждением или не включает заданное поле, возвращается NULL. Обычно значения полей не включают завершающий символ перевода строки. Вызывающая функция не должна напрямую освобождать память, выделенную под результат. Она будет освобождена, когда связанный маркер PGresult будет передан функции PQclear.

Доступны следующие коды полей:

  • PG_DIAG_SEVERITY
    Серьезность; поле содержит ERROR, FATAL или PANIC (в сообщении об ошибке), либо WARNING, NOTICE, DEBUG, INFO или LOG (в сообщении с замечанием), либо локализованный перевод одного из этих значений (ОШИБКА, КРИТИЧНО, ПАНИКА, ПРЕДУПРЕЖДЕНИЕ, ЗАМЕЧАНИЕ, ОТЛАДКА, ИНФОРМАЦИЯ, СООБЩЕНИЕ соответственно). Присутствует всегда.

  • PG_DIAG_SEVERITY_NONLOCALIZED
    Серьезность; поле содержит ERROR, FATAL или PANIC (в сообщении об ошибке), либо WARNING, NOTICE, DEBUG, INFO или LOG (в сообщении с замечанием). Оно идентично полю PG_DIAG_SEVERITY за исключением того, что его содержимое никогда не локализуется.

  • PG_DIAG_SQLSTATE
    Код SQLSTATE для ошибки. Код SQLSTATE идентифицирует тип случившейся ошибки; его могут использовать клиентские приложения, чтобы выполнять конкретные операции (например, обработку ошибок) в ответ на конкретную ошибку базы данных. Список возможных кодов SQLSTATE см. в главе Коды ошибок. Это поле не является локализуемым и присутствует всегда.

  • PG_DIAG_MESSAGE_PRIMARY
    Основное сообщение об ошибке, удобное для восприятия человеком (как правило, состоит из одной строки). Присутствует всегда.

  • PG_DIAG_MESSAGE_DETAIL
    Подробности: необязательное дополнительное сообщение об ошибке, содержащее больше сведений о проблеме. Может состоять из нескольких строк.

  • PG_DIAG_MESSAGE_HINT
    Совет: необязательная рекомендация о том, как справиться с проблемой. Оно должно отличаться от подробностей в том, что здесь предлагается совет (возможно, неподходящий), а не голые факты. Может состоять из нескольких строк.

  • PG_DIAG_STATEMENT_POSITION
    Строка, содержащая десятичное целое число, указывающее позицию курсора ошибки в виде индекса в оригинальной строке оператора. Первый символ имеет индекс 1, и позиция измеряется в символах, а не в байтах.

  • PG_DIAG_INTERNAL_POSITION
    Это поле определяется так же, как и поле PG_DIAG_STATEMENT_POSITION, но используется, когда позиция курсора относится к команде, сгенерированной внутренне, а не к команде, предложенной клиентом. Когда появляется это поле, всегда будет появляться и поле PG_DIAG_INTERNAL_QUERY.

  • PG_DIAG_INTERNAL_QUERY
    Текст внутренне сгенерированной команды, завершившейся сбоем. Это может быть, например, запрос SQL, выданный функцией на PL/pgSQL.

  • PG_DIAG_CONTEXT
    Обозначение контекста, в котором произошла ошибка. В настоящее время оно включает обратную трассировку стека вызовов активных функций процедурного языка и запросов, сгенерированный внутренне. Трассировка выводится по одной записи на строку, причем первой идет самая последняя запись.

  • PG_DIAG_SCHEMA_NAME
    Если ошибка была связана с конкретным объектом базы данных, в этом поле будет имя схемы, содержащей данный объект, если таковой имеется.

  • PG_DIAG_TABLE_NAME
    Если ошибка была связана с конкретной таблицей, в этом поле будет имя данной таблицы. (За именем схемы таблицы обратитесь к полю с именем схемы.)

  • PG_DIAG_COLUMN_NAME
    Если ошибка была связана с конкретным столбцом таблицы, в этом поле будет имя данного столбца. (Для идентификации таблицы обратитесь к полям с именами схемы и таблицы.)

  • PG_DIAG_DATATYPE_NAME
    Если ошибка была связана с конкретным типом данных, в этом поле будет имя этого типа. (За именем схемы типа данных обратитесь к полю с именем схемы.)

  • PG_DIAG_CONSTRAINT_NAME
    Если ошибка была связана с конкретным ограничением, в этом поле будет имя данного ограничения. Для получения связанной таблицы или домена обратитесь к полям, перечисленным выше. (С этой целью индексы рассматриваются как ограничения, даже если они не были созданы с помощью синтаксиса ограничений.)

  • PG_DIAG_SOURCE_FILE
    Имя файла, содержащего расположение в исходном коде, для которого было выдано сообщение об ошибке.

  • PG_DIAG_SOURCE_LINE
    Номер строки, содержащей расположение в исходном коде, для которого было выдано сообщение об ошибке.

  • PG_DIAG_SOURCE_FUNCTION
    Имя функции в исходном коде, сообщающей об ошибке.

Примечание
Поля для имени схемы, имени таблицы, имени столбца, имени типа данных и имени ограничения предоставляются только для ограниченного числа типов ошибок; см. главу Коды ошибок. Не стоит рассчитывать, что присутствие любого из этих полей гарантирует присутствие другого поля. Ключевые источники ошибок соблюдают взаимосвязи, рассмотренные выше, но пользовательские функции могут использовать эти поля иными способами. Подобным же образом не стоит рассчитывать, что эти поля обозначают актуальные объекты в текущей базе данных.

Клиент отвечает за форматирование отображаемой информации в соответствии с его потребностями; в частности, он должен по мере необходимости разбивать длинные строки. Символы перевода строки, фигурирующие в полях сообщения об ошибке, следует обрабатывать как разрывы абзацев, а не строк.

Ошибки, внутренне сгенерированные libpq, будут иметь поля серьезности и основного сообщения, но, как правило, никаких других полей.

Обратите внимание, что поля ошибки доступны только из объектов PGresult, но не из объектов PGconn; не существует функции PQerrorField.

PQclear

Освобождает память, связанную с PGresult. Результат каждой команды должен быть освобожден функцией PQclear, когда он больше не нужен.

void PQclear(PGresult *res);

Сохранять объект PGresult можно столько, сколько понадобится; он не исчезает ни при выполнении новой команды, ни даже при закрытии соединения. Чтобы избавиться от него, следует вызвать функцию PQclear. Если этого не делать, это приведет к утечкам памяти в вашем приложении.


Извлечение информации о результате запроса

Эти функции применяются для извлечения информации из объекта PGresult, который представляет результат успешного запроса (то есть запроса со статусом PGRES_TUPLES_OK или PGRES_SINGLE_TUPLE). Также их можно использовать для извлечения информации из успешной операции DESCRIBE: ее результат содержит все ту же информацию о столбцах, которую предоставило бы фактическое выполнение запроса, но не содержит ни одной строки. Для объектов с другими значениями статуса эти функции будут вести себя так, словно результат не содержит ни строк, ни столбцов.

PQntuples

Возвращает количество строк (кортежей) в результате запроса. (Обратите внимание, что объекты PGresult не могут содержать больше INT_MAX строк, так что достаточно результата типа int.)

int PQntuples(const PGresult *res);

PQnfields

Возвращает количество столбцов (полей) в каждой строке результата запроса.

int PQnfields(const PGresult *res);

PQfname

Возвращает имя столбца, соответствующего данному номеру столбца. Номера столбцов начинаются с 0. Вызывающая функция не должна напрямую освобождать память, выделенную под результат. Она будет освобождена, когда связанный маркер PGresult будет передан функции PQclear.

char *PQfname(const PGresult *res,
              int column_number);

Если номер столбца выходит за пределы допустимого диапазона, возвращается NULL.

PQfnumber

Возвращает номер столбца, соответствующего данному имени столбца.

int PQfnumber(const PGresult *res,
              const char *column_name);

Если заданное имя не соответствует ни одному столбцу, возвращается -1.

Заданное имя воспринимается как идентификатор в команде SQL, то есть если оно не заключено в кавычки, то переводится в нижний регистр. Например, задав результат запроса, сгенерированный из этой команды SQL:

SELECT 1 AS FOO, 2 AS "BAR";

мы бы получили такие результаты:

PQfname(res, 0)              foo
PQfname(res, 1)              BAR
PQfnumber(res, "FOO")        0
PQfnumber(res, "foo")        0
PQfnumber(res, "BAR")        -1
PQfnumber(res, "\"BAR\"")    1

PQftable

Возвращает OID таблицы, из которой был получен данный столбец. Номера столбцов начинаются с 0.

Oid PQftable(const PGresult *res,
             int column_number);

Если номер столбца выходит за пределы допустимого диапазона или указанный столбец не является простой ссылкой на столбец таблицы, то возвращается InvalidOid. Чтобы точно определить, к какой таблице происходит обращение, можно сделать запрос к системной таблице pg_class.

Тип Oid и константа InvalidOid будут определены, когда вы включите заголовочный файл libpq. Они будут принадлежать к одному из целочисленных типов.

PQftablecol

Возвращает номер столбца (в пределах его таблицы), формирующего результирующий столбец заданного запроса. Номера результирующих столбцов запроса начинаются с 0, но столбцы таблицы имеют ненулевые номера.

int PQftablecol(const PGresult *res,
                int column_number);

Если номер столбца выходит за пределы допустимого диапазона или указанный столбец не является простой ссылкой на столбец таблицы, то возвращается ноль.

PQfformat

Возвращает код формата, показывающий формат данного столбца. Номера столбцов начинаются с 0.

int PQfformat(const PGresult *res,
              int column_number);

Нулевой код формата указывает на текстовое представление данных, тогда как код формата, равный единице, указывает на двоичное представление. (Остальные коды зарезервированы для определения в будущем.)

PQftype

Возвращает тип данных, соответствующий данному номеру столбца. Возвращаемое целое число является внутренним номером OID этого типа. Номера столбцов начинаются с 0.

Oid PQftype(const PGresult *res,
            int column_number);

Чтобы получить имена и свойства различных типов данных, можно сделать запрос к системной таблице pg_type. OID встроенных типов данных определяются в файле catalog/pg_type_d.h каталога include установки QHB.

PQfmod

Возвращает модификатор типа для столбца, соответствующего данному номеру столбца. Номера столбцов начинаются с 0.

int PQfmod(const PGresult *res,
           int column_number);

Интерпретация значений модификаторов является типоспецифичной; обычно они показывают точность или пределы размеров. Значение -1 используется, чтобы указать «нет доступной информации». Большинство типов данных не применяют модификаторы, и в этом случае значение всегда будет -1.

PQfsize

Возвращает размер (в байтах) столбца, соответствующего данному номеру столбца. Номера столбцов начинаются с 0.

int PQfsize(const PGresult *res,
            int column_number);

Функция PQfsize возвращает размер пространства, выделенного для этого столбца в строке базы данных; иными словами, это размер внутреннего представления сервера для этого типа данных. (Поэтому в действительности он не очень полезен для клиентов.) Отрицательное значение показывает, что это тип данных переменной длины.

PQbinaryTuples

Возвращает 1, если PGresult содержит двоичные данные, и 0, если он содержит текстовые данные.

int PQbinaryTuples(const PGresult *res);

Эта функция считается устаревшей (за исключением использования совместно с командой COPY), поскольку в одном объекте PGresult могут в одних столбцах содержаться текстовые данные, а в других — двоичные. Предпочтительнее использовать функцию PQfformat. Функция PQbinaryTuples возвращает 1, только если все столбцы результата являются двоичными (формат 1).

PQgetvalue

Возвращает значение одного поля из одной строки в PGresult. Номера строк и столбцов начинаются с 0. Вызывающая функция не должна напрямую освобождать память, выделенную под результат. Она будет освобождена, когда связанный маркер PGresult будет передан функции PQclear.

char *PQgetvalue(const PGresult *res,
                 int row_number,
                 int column_number);

Для данных в текстовом формате значение, возвращаемое функцией PQgetvalue, является представлением значения поля в виде символьной строки с завершающим нулем. Для данных в двоичном формате это значение является двоичным представлением, определяемым функциями typsend и typreceive конкретного типа данных. (В действительности в этом случае после значения тоже следует нулевой байт, но обычно от этого нет пользы, поскольку это значение, скорее всего, уже содержит вложенные пустые поля.)

Если значение поля равно NULL, возвращается пустая строка. Чтобы отличить значения NULL от пустых строковых значений, используйте функцию PQgetisnull.

Указатель, возвращаемый функцией PQgetvalue, указывает на область памяти, являющуюся частью структуры PGresult. Не следует модифицировать данные, на которые он указывает, вместо этого необходимо явно скопировать их в другую область памяти, если они будут использоваться и после прекращения существования самой структуры PGresult.

PQgetisnull

Проверяет поле на отсутствие значения NULL. Номера строк и столбцов начинаются с 0.

int PQgetisnull(const PGresult *res,
                int row_number,
                int column_number);

Эта функция возвращает 1, если поле равно NULL, и 0, если оно содержит значение, отличное от NULL. (Обратите внимание, что для поля с NULL функция PQgetvalue вернет пустую строку, а не пустой указатель.)

PQgetlength

Возвращает фактическую длину значения поля в байтах. Номера строк и столбцов начинаются с 0.

int PQgetlength(const PGresult *res,
                int row_number,
                int column_number);

Это фактическая длина данных для конкретного значения данных, то есть размер объекта, на который указывает функция PQgetvalue. Для текстового формата данных это то же самое, что и strlen(). Для двоичного формата это существенная информация. Обратите внимание, что при получении фактической длины данных не стоит рассчитывать на функцию PQfsize.

PQnparams

Возвращает количество параметров подготовленного оператора.

int PQnparams(const PGresult *res);

Эта функция полезна только при изучении результатов функции PQdescribePrepared. Для остальных типов запросов она вернет ноль.

PQparamtype

Возвращает тип данных указанного параметра оператора. Номера параметров начинаются с 0.

Oid PQparamtype(const PGresult *res, int param_number);

Эта функция полезна только при изучении результатов функции PQdescribePrepared. Для остальных типов запросов она вернет ноль.

PQprint

Выводит все строки и, при желании, имена столбцов в заданных поток вывода.

void PQprint(FILE *fout,      /* поток вывода */
             const PGresult *res,
             const PQprintOpt *po);
typedef struct
{
    pqbool  header;      /* вывести заголовки полей и счетчик строк */
    pqbool  align;       /* выравнивать поля */
    pqbool  standard;    /* старый неудобный формат */
    pqbool  html3;       /* выводить HTML-таблицы */
    pqbool  expanded;    /* расширять таблицы */
    pqbool  pager;       /* при необходимости использовать скрипт постраничного вывода */
    char    *fieldSep;   /* разделитель полей */
    char    *tableOpt;   /* атрибуты для элемента HTML-таблицы */
    char    *caption;    /* подпись к HTML-таблице */
    char    **fieldName; /* массив заменителей для имен полей с завершающим нулем */
} PQprintOpt;

Раньше эта функция использовалась утилитой psql для вывода результатов запросов, но больше не используется. Обратите внимание, что она предполагает, что все данные находятся в текстовом формате.


Извлечение другой информации о результате

Эти функции применяются для извлечения из объектов PGresult остальной информации.

PQcmdStatus

Возвращает тег статуса из команды SQL, сгенерировавшей PGresult.

char *PQcmdStatus(PGresult *res);

Обычно это просто имя команды, но может включать и дополнительные данные, например количество обработанных строк. Вызывающая функция не должна напрямую освобождать память, выделенную под результат. Она будет освобождена, когда связанный маркер PGresult будет передан функции PQclear.

PQcmdTuples

Возвращает количество строк, затронутых командой SQL.

char *PQcmdTuples(PGresult *res);

Эта функция возвращает сроку, содержащую количество строк, затронутых оператором SQL, который сгенерировал PGresult. Эту функцию можно использовать только после выполнения оператора SELECT, CREATE TABLE AS, INSERT, UPDATE, DELETE, MERGE, MOVE, FETCH или COPY либо после выполнения оператора EXECUTE с подготовленным запросом, содержащим оператор INSERT, UPDATE, DELETE или MERGE. Если PGresult был сгенерирован какой-то другой командой, функция PQcmdTuples возвращает пустую строку. Вызывающая функция не должна напрямую освобождать память, выделенную под результат. Она будет освобождена, когда связанный маркер PGresult будет передан функции PQclear.

PQoidValue

Возвращает OID добавленной строки, если командой SQL была INSERT, которая добавила ровно одну строку в таблицу, имеющую идентификаторы OID, или EXECUTE с подготовленным запросом, содержащим подходящий оператор INSERT. В противном случае эта функция возвращает InvalidOid. Кроме того, эта функция возвратит InvalidOid, если таблица, затронутая оператором INSERT не содержит идентификаторы OID.

Oid PQoidValue(const PGresult *res);

PQoidStatus

Эта функция считается устаревшей (заменена на функцию PQoidValue) и не ориентирована на многопоточное выполнение. Она возвращает строку с OID добавленной строки, тогда как функция PQoidValue возвращает значение OID.

char *PQoidStatus(const PGresult *res);

Экранирование строк для включения в команды SQL

PQescapeLiteral

char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);

Функция PQescapeLiteral экранирует строку для использования внутри команды SQL. Это полезно при добавлении в команды SQL значений данных в виде строковых констант. Определенные символы (например, кавычки и обратные слэши) следует экранировать, чтобы предотвратить их специальную интерпретацию синтаксическим анализатором SQL. Эту операцию выполняет функция PQescapeLiteral.

Функция PQescapeLiteral возвращает экранированную версию параметра str, размещенную в области памяти, выделенной с помощью функции malloc(). Эту память следует освободить с помощью функции PQfreemem(), когда результат будет уже не нужен. Завершающий нулевой байт не требуется и не должен учитываться в параметре length. (Если завершающий нулевой байт обнаруживается до обработки length байт, функция PQescapeLiteral останавливается на этом нулевом байте, так что ее поведение напоминает strncpy.) В возвращаемой строке все специальные символы заменяются таким образом, что их может адекватно обработать синтаксический анализатор строковых литералов QHB. Также добавляется завершающий нулевой байт. Апострофы, которые должны окружить строковые литералы QHB, включаются в результирующую строку.

При ошибке функция PQescapeLiteral возвращает NULL, а в объект conn сохраняется соответствующее сообщение.

Совет
Особенно важно выполнять надлежащее экранирование при обработке строк, полученных из ненадежного источника. Иначе возникает угроза безопасности: вы уязвимы к атакам с «инъекцией SQL», при которых в вашу базу данных поступают нежелательные команды SQL.

Обратите внимание, что экранирование излишне и даже некорректно проводить, когда значение данных передается в виде отдельного параметра в функцию PQexecParams или родственные ей функции.

PQescapeIdentifier

char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);

Функция PQescapeIdentifier экранирует строку, предназначенную для использования в качестве идентификатора SQL, например имени таблицы, столбца или функции. Это полезно, когда идентификатор, предоставленный пользователем, может содержать специальные символы, которые иначе не будут интерпретироваться синтаксическим анализатором SQL как часть идентификатора, или когда идентификатор может содержать символы в верхнем регистре, который нужно сохранить.

Функция PQescapeIdentifier возвращает версию параметра str, экранированную как идентификатор SQL и размещенную в области памяти, выделенной с помощью функции malloc(). Эту память следует освободить с помощью функции PQfreemem(), когда результат будет уже не нужен. Завершающий нулевой байт не требуется и не должен учитываться в параметре length. (Если завершающий нулевой байт обнаруживается до обработки length байт, функция PQescapeIdentifier останавливается на этом нулевом байте, так что ее поведение напоминает strncpy.) В возвращаемой строке все специальные символы заменяются таким образом, что ее можно адекватно обработать как идентификатор SQL. Также добавляется завершающий нулевой байт. Кроме того, возвращаемая строка будет заключена в кавычки.

При ошибке функция PQescapeIdentifier возвращает NULL, а в объект conn сохраняется соответствующее сообщение.

Совет
Как и в случае со строковыми литералами, для предотвращения атак с инъекцией SQL идентификаторы SQL следует экранировать, когда они получены из ненадежного источника.

PQescapeStringConn

size_t PQescapeStringConn(PGconn *conn,
                          char *to, const char *from, size_t length,
                          int *error);

Функция PQescapeStringConn экранирует строковые литералы подобно функции PQescapeLiteral. Однако, в отличие от PQescapeLiteral, за предоставление буфера надлежащего размера отвечает вызывающая функция. Более того, функция PQescapeStringConn не генерирует апострофы, которые должны окружать строковые литералы QHB; они должны предоставляться в команде SQL, в которую вставляется результат. Параметр from указывает на первый символ строки, который нужно экранировать, а параметр length задает количество байтов в этой строке. Завершающий нулевой байт не требуется и не должен учитываться в параметре length. (Если завершающий нулевой байт обнаруживается до обработки length байт, функция PQescapeStringConn останавливается на этом нулевом байте, так что ее поведение напоминает strncpy.) Параметр to должен указывать на буфер, способный вместить как минимум на один байт больше удвоенного значения length, в противном случае поведение функции не определено. Кроме того, поведение, скорее всего, будет неопределенным, если строки to и from перекрываются.

Если параметр error не равен NULL, то в *error в случае успеха устанавливается ноль, а в случае ошибки — ненулевое значение. В настоящее время единственным возможным условием ошибки является недопустимая многобайтовая кодировка в исходной строке. В случае ошибки выходная строка все равно генерируется, но можно ожидать, что сервер отвергнет ее как некорректную. При ошибке в объект conn сохраняется соответствующее сообщение, независимо от того, равен ли NULL параметр error.

Функция PQescapeStringConn возвращает количество байтов, записанных в to, не включая завершающий нулевой байт.

PQescapeString

Функция PQescapeString является более старой, выводимой из употребления версией функции PQescapeStringConn.

size_t PQescapeString (char *to, const char *from, size_t length);

Единственное отличие от функции PQescapeStringConn заключается в том, что функция PQescapeString не принимает параметры PGconn и error. Из-за этого она не может скорректировать свое поведение в зависимости от свойств подключения (например, кодировки символов) и, как следствие, может выдавать неверные результаты. Кроме того, она не способна сообщать об ошибках.

Функцию PQescapeString можно безопасно применять в клиентских программах, работающих только с одним соединением с QHB за раз (в этом случае она может найти то, что ей нужно знать, «за кадром»). В других контекстах она представляет собой угрозу безопасности, и следует предпочесть использование функции PQescapeStringConn.

PQescapeByteaConn

Экранирует двоичные данные для использования внутри команды SQL с типом bytea. Как и в случае с PQescapeStringConn, эта функция применяется, только когда данные добавляются в строку команды SQL напрямую.

unsigned char *PQescapeByteaConn(PGconn *conn,
                                 const unsigned char *from,
                                 size_t from_length,
                                 size_t *to_length);

Определенные значения байтов нужно экранировать при использовании в качестве части литерала типа bytea в операторе SQL. Функция PQescapeByteaConn экранирует байты с помощью шестнадцатеричного кодирования или обратного слэша. Подробную информацию см. в разделе Двоичные типы данных.

Параметр from указывает на первый байт строки, который нужно экранировать, а параметр from_length задает количество байтов в этой двоичной строке. (Завершающий нулевой байт не требуется и не должен учитываться.) Параметр to_length указывает на переменную, которая будет содержать длину результирующей экранированной строки. Эта длина включает завершающий нулевой байт результата.

Функция PQescapeByteaConn возвращает экранированную версию двоичной строки из параметра from, размещенную в области памяти, выделенной с помощью функции malloc(). Эту память следует освободить с помощью функции PQfreemem(), когда результат будет уже не нужен. В возвращаемой строке все специальные символы заменяются таким образом, что их могут адекватно обработать синтаксический анализатор строковых литералов QHB и функция ввода типа bytea. Также добавляется завершающий нулевой байт. Апострофы, которые должны окружать строковые литералы QHB, не являются частью результирующей строки.

При ошибке возвращается пустой указатель, а в объект conn сохраняется соответствующее сообщение. В настоящее время единственной возможной ошибкой является нехватка памяти для результирующей строки.

PQescapeBytea

Функция PQescapeBytea является более старой, выводимой из употребления версией функции PQescapeByteaConn.

unsigned char *PQescapeBytea(const unsigned char *from,
                             size_t from_length,
                             size_t *to_length);

Единственное отличие от функции PQescapeByteaConn заключается в том, что функция PQescapeBytea не принимает параметр PGconn. Из-за этого PQescapeBytea можно безопасно применять в клиентских программах, работающих только с одним соединением с QHB за раз (в этом случае она может найти то, что ей нужно знать, «за кадром»). Она может выдавать неверные результаты при использовании в программах, имеющих несколько соединений с базами данных (в таких случаях применяйте функцию PQescapeByteaConn).

PQunescapeBytea

Преобразует строковое представление двоичных данных в двоичные данные — обратно поведению функции PQescapeByteaConn. Она требуется при извлечении данных типа bytea в текстовом формате, но не при извлечении их в двоичном формате.

unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);

Параметр from указывает на такую строку, какую могла бы вернуть функция PQgetvalue, примененная к столбцу типа bytea. Функция PQunescapeBytea преобразует это строковое представление в его двоичное представление. Она возвращает указатель на буфер, выделенный с помощью функции malloc(), или NULL при ошибке и помещает размер буфера в параметр to_length. Результат следует освободить с помощью функции PQfreemem, когда он будет уже не нужен.

Это преобразование не вполне обратно действию функции PQescapeByteaConn, поскольку не ожидается, что строка, полученная от PQgetvalue, будет «экранированной». В частности, это означает, что нет необходимости учитывать заключение строки в кавычки, и поэтому параметр PGconn не требуется.