31.3. Функции выполнения команд#
31.3. Функции выполнения команд #
После успешного установления соединения с сервером базы данных используются функции, описанные здесь, для выполнения SQL-запросов и команд.
31.3.1. Основные функции #
PQexec
#Отправляет команду на сервер и ожидает результата.
PGresult *PQexec(PGconn *conn, const char *command);
Возвращает указатель на структуру
PGresult
или, возможно, нулевой указатель. Обычно будет возвращен ненулевой указатель, за исключением ситуаций, связанных с нехваткой памяти или серьезными ошибками, такими как невозможность отправки команды на сервер. Для проверки возвращаемого значения на наличие ошибок (включая значение нулевого указателя, в этом случае будет возвращено значениеPGRES_FATAL_ERROR
) следует вызвать функциюPQresultStatus
. ИспользуйтеPQerrorMessage
для получения дополнительной информации об ошибках такого рода.
Строка команды может содержать несколько SQL-команд (разделенных точкой с запятой). Несколько запросов, отправленных в одном вызове PQexec
, обрабатываются в одной транзакции, если в строке запроса нет явных команд BEGIN
/COMMIT
для разделения ее на несколько транзакций. (См. Раздел 52.2.2.1 для получения дополнительной информации о том, как сервер обрабатывает множественные строки запросов). Однако следует отметить, что возвращаемая структура 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[]
Определяет фактические значения параметров. Нулевой указатель в этом массиве означает, что соответствующий параметр является нулевым; в противном случае указатель указывает на нуль-терминированную текстовую строку (для текстового формата) или двоичные данные в формате, ожидаемом сервером (для двоичного формата).
paramLengths[]
Определяет фактическую длину данных для параметров в бинарном формате. Он игнорируется для нулевых параметров и параметров в текстовом формате. Указатель на массив может быть нулевым, когда нет бинарных параметров.
paramFormats[]
Определяет, являются ли параметры текстовыми (вставьте ноль в элемент массива для соответствующего параметра) или двоичными (вставьте единицу в элемент массива для соответствующего параметра). Если указатель массива равен null, то все параметры считаются текстовыми строками.
Все значения, передаваемые в двоичном формате, требуют знания внутреннего представления, ожидаемого бэкендом. Например, целые числа должны быть переданы в сетевом порядке байтов. Передача значений типа
numeric
требует знания формата хранения на сервере, реализованного в файлеsrc/backend/utils/adt/numeric.c::numeric_send()
иsrc/backend/utils/adt/numeric.c::numeric_recv()
.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
, содержимое которого указывает на успешное или неудачное выполнение на стороне сервера. Пустой результат указывает на нехватку памяти или невозможность отправить команду вообще. Используйте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
. ФункцииPQnparams
иPQparamtype
могут быть применены к этомуPGresult
для получения информации о параметрах подготовленного оператора, а функцииPQnfields
,PQfname
,PQftype
и т. д. предоставляют информацию о столбцах результата (если они есть) оператора.PQdescribePortal
#Отправляет запрос для получения информации о указанном портале и ожидает его завершения.
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortal
позволяет приложению получить информацию о ранее созданном портале. (libpq не предоставляет прямого доступа к порталам, но вы можете использовать эту функцию для изучения свойств курсора, созданного с помощью SQL-командыDECLARE CURSOR
).portalName
может быть""
илиNULL
для ссылки на безымянный портал, в противном случае это должно быть имя существующего портала. При успешном выполнении возвращаетсяPGresult
со статусомPGRES_COMMAND_OK
. ФункцииPQnfields
,PQfname
,PQftype
и т. д. могут быть применены кPGresult
для получения информации о столбцах результата (если они есть) портала.
Структура 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
#Началась передача данных в режиме копирования на сервер.
PGRES_BAD_RESPONSE
#Ответ сервера не был понят.
PGRES_NONFATAL_ERROR
#Произошла некритическая ошибка (уведомление или предупреждение).
PGRES_FATAL_ERROR
#Произошла критическая ошибка.
PGRES_COPY_BOTH
#Началась передача данных в формате Copy In/Out (на и от сервера). Эта функция в настоящее время используется только для потоковой репликации, поэтому такой статус не должен возникать в обычных приложениях.
PGRES_SINGLE_TUPLE
#Структура
PGresult
содержит единственный кортеж результата текущей команды. Этот статус возникает только при выборе режима одиночной строки для запроса (см. Раздел 31.6).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
или другими функциями выполнения запросов; результаты этого типа вместо этого передаются обработчику уведомлений (см. Раздел 31.13).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 не является ошибочным результатом”. Возвращаемая строка включает завершающий символ перехода строки.В отличие от большинства других функций для извлечения данных из
PGresult
, результатом этой функции является новая выделенная строка. Вызывающая сторона должна освободить ее, используя функциюPQfreemem()
, когда строка больше не нужна.Возможно возвращение NULL, если недостаточно памяти.
PQresultErrorField
#Возвращает отдельное поле отчета об ошибке.
char *PQresultErrorField(const PGresult *res, int fieldcode);
fieldcode
- это идентификатор поля ошибки; см. перечисленные ниже символы.NULL
возвращается, еслиPGresult
не является результатом ошибки или предупреждения, или не содержит указанное поле. Значения полей обычно не содержат завершающего символа перехода строки. Вызывающая сторона не должна освобождать результат напрямую. Он будет освобожден, когда связанный с ним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
, за исключением того, что содержимое никогда не локализуется. Присутствует только в отчетах, созданных в PostgreSQL версии 9.6 и более поздних.PG_DIAG_SQLSTATE
#Код SQLSTATE для ошибки. Код SQLSTATE идентифицирует тип возникшей ошибки; он может быть использован клиентскими приложениями для выполнения определенных операций (например, обработки ошибок) в ответ на конкретную ошибку базы данных. Для списка возможных кодов SQLSTATE см. Предметный указатель A. Это поле не является локализуемым и всегда присутствует.
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
#Имя функции исходного кода, сообщающей об ошибке.
Примечание
Все поля для имени схемы, имени таблицы, имени столбца, имени типа данных и имени ограничения предоставляются только для ограниченного числа типов ошибок; см. Предметный указатель A. Не предполагайте, что наличие любого из этих полей гарантирует наличие другого поля. Основные источники ошибок соблюдают указанные выше взаимосвязи, но пользовательские определенные функции могут использовать эти поля по-другому. В том же духе, не предполагайте, что эти поля обозначают современные объекты в текущей базе данных.
Клиент несет ответственность за форматирование отображаемой информации в соответствии с его потребностями; в частности, он должен разбивать длинные строки по мере необходимости. Символы новой строки, появляющиеся в полях сообщений об ошибках, должны рассматриваться как разрывы абзацев, а не строк.
Внутренние ошибки, генерируемые libpq, обычно содержат только уровень серьезности и основное сообщение, без других полей.
Обратите внимание, что поля ошибок доступны только из объектов
PGresult
, а не из объектовPGconn
; функцияPQerrorField
отсутствует.PQclear
#Освобождает память, связанную с
PGresult
. Каждый результат команды должен быть освобожден с помощьюPQclear
, когда он больше не нужен.void PQclear(PGresult *res);
Если аргумент является указателем на
NULL
, операция не выполняется.Вы можете сохранить объект
PGresult
на протяжении всего времени его использования; он не исчезает при выполнении новой команды или даже при закрытии соединения. Чтобы избавиться от него, необходимо вызвать функциюPQclear
. Если этого не сделать, это может привести к утечкам памяти в вашем приложении.
31.3.2. Получение информации о результате запроса #
Эти функции используются для извлечения информации из объекта PGresult
, который представляет собой успешный результат запроса (то есть, имеющий статус PGRES_TUPLES_OK
или PGRES_SINGLE_TUPLE
). Они также могут использоваться для извлечения информации из успешной операции Describe: результат 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
#Возвращает тип данных, связанный с заданным номером столбца. Возвращаемое целое число является внутренним идентификатором типа. Номера столбцов начинаются с 0.
Oid PQftype(const PGresult *res, int column_number);
Вы можете запросить системную таблицу
pg_type
, чтобы получить имена и свойства различных типов данных. OID встроенных типов данных определены в файлеcatalog/pg_type_d.h
в каталогеinclude
установки Tantor SE-1C.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. См.
PQgetisnull
для различия между значениями null и пустыми строками.Указатель, возвращаемый функцией
PQgetvalue
, указывает на хранилище, которое является частью структурыPGresult
. Нельзя изменять данные, на которые он указывает, и необходимо явно скопировать данные в другое хранилище, если они должны использоваться после завершения существования структурыPGresult
самой по себе.PQgetisnull
#Проверяет поле на наличие значения NULL. Номера строки и столбца начинаются с 0.
int PQgetisnull(const PGresult *res, int row_number, int column_number);
Эта функция возвращает 1, если поле является пустым (null), и 0, если оно содержит значение not-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, /* output stream */ const PGresult *res, const PQprintOpt *po); typedef struct { pqbool header; /* print output field headings and row count */ pqbool align; /* fill align the fields */ pqbool standard; /* old brain dead format */ pqbool html3; /* output HTML tables */ pqbool expanded; /* expand tables */ pqbool pager; /* use pager for output if needed */ char *fieldSep; /* field separator */ char *tableOpt; /* attributes for HTML table element */ char *caption; /* HTML table caption */ char **fieldName; /* null-terminated array of replacement field names */ } PQprintOpt;
Эта функция ранее использовалась приложением psql для печати результатов запросов, но это уже не так. Обратите внимание, что она предполагает, что все данные находятся в текстовом формате.
31.3.3. Получение другой информации о результате #
Эти функции используются для извлечения другой информации из объектов 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);
31.3.4. Экранирование строк для включения в 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
). Возвращаемая строка заменяет все специальные символы, чтобы их можно было правильно обработать парсером строковых литералов Tantor SE-1C. Также добавляется завершающий нулевой байт. Апострофы которые должны окружать строковые литералы Tantor SE-1C, включены в результирующую строку.При возникновении ошибки,
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
не генерирует апострофы, которые должны окружать строковые литералы Tantor SE-1C; они должны быть предоставлены в SQL-команде, в которую будет вставлен результат. Параметрfrom
указывает на первый символ строки, который должен быть экранирован, а параметрlength
указывает количество байтов в этой строке. Завершающий нулевой байт не требуется и не должен учитываться вlength
. (Если завершающий нулевой байт найден до обработкиlength
байтов,PQescapeStringConn
останавливается на нуле; поведение похоже наstrncpy
). Параметрto
должен указывать на буфер, который может вместить как минимум на один байт больше, чем двойное значениеlength
, в противном случае поведение не определено. Поведение также не определено, если строкиto
иfrom
перекрываются.Если параметр
error
не равенNULL
, то*error
устанавливается в ноль в случае успеха и в ненулевое значение в случае ошибки. В настоящее время единственные возможные условия ошибки связаны с недопустимой многобайтовой кодировкой в исходной строке. Выходная строка все равно генерируется при ошибке, но можно ожидать, что сервер отклонит ее как некорректную. При ошибке подходящее сообщение сохраняется в объектеconn
, независимо от того, является лиerror
равнымNULL
.PQescapeStringConn
возвращает количество записанных байтов вto
, не включая завершающий нулевой байт.PQescapeString
#PQescapeString
- это старая, устаревшая версия функцииPQescapeStringConn
.size_t PQescapeString (char *to, const char *from, size_t length);
Разница между
PQescapeStringConn
иPQescapeString
заключается только в том, чтоPQescapeString
не принимает параметрыPGconn
илиerror
. Из-за этого он не может настраивать свое поведение в зависимости от свойств соединения (например, кодировки символов) и, следовательно, может давать неправильные результаты. Кроме того, у него нет способа сообщать об ошибках.PQescapeString
можно безопасно использовать в клиентских программах, которые работают только с одним соединением Tantor SE-1C за раз (в этом случае она может узнать, что ей нужно знать “за кулисами”). В других контекстах это представляет угрозу безопасности и следует избегать в пользу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
экранирует байты с использованием либо шестнадцатеричного кодирования, либо экранирования обратной косой чертой. См. Раздел 8.4 для получения дополнительной информации.Параметр
from
указывает на первый байт строки, который должен быть экранирован, а параметрfrom_length
указывает количество байтов в этой двоичной строке. (Завершающий нулевой байт не является необходимым и не учитывается). Параметрto_length
указывает на переменную, которая будет содержать длину результирующей экранированной строки. Длина этой строки включает завершающий нулевой байт результата.PQescapeByteaConn
возвращает экранированную версию двоичной строки параметраfrom
в памяти, выделенной с помощью функцииmalloc()
. Эта память должна быть освобождена с помощью функцииPQfreemem()
, когда результат больше не нужен. Возвращаемая строка имеет все специальные символы заменены, чтобы их можно было правильно обработать парсером строковых литералов Tantor SE-1C и функцией вводаbytea
. Также добавляется завершающий нулевой байт. Апострофы, в которые заключают строковые литералы Tantor SE-1C, не являются частью результирующей строки.При ошибке возвращается нулевой указатель, а соответствующее сообщение об ошибке сохраняется в объекте
conn
. В настоящее время единственная возможная ошибка - недостаток памяти для строки результата.PQescapeBytea
#PQescapeBytea
- это старая, устаревшая версия функцииPQescapeByteaConn
.unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length);
Разница между
PQescapeByteaConn
иPQescapeBytea
заключается только в том, чтоPQescapeBytea
не принимает параметрPGconn
. Из-за этогоPQescapeBytea
может быть безопасно использован только в клиентских программах, которые используют одно соединение Tantor SE-1C за раз (в этом случае она может узнать все, что ей нужно “за кулисами”). Однако, если она используется в программах, которые используют несколько соединений с базой данных, она может дать неправильные результаты (в таких случаях следует использоватьPQescapeByteaConn
).PQunescapeBytea
#Преобразует строковое представление двоичных данных в двоичные данные - обратное действие к
PQescapeBytea
. Это необходимо при получении данных типаbytea
в текстовом формате, но не при получении их в двоичном формате.unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
Параметр
from
указывает на строку, такую как может быть возвращенаPQgetvalue
, когда применяется к столбцуbytea
.PQunescapeBytea
преобразует эту строковую представление в двоичное представление. Он возвращает указатель на буфер, выделенный с помощьюmalloc()
, илиNULL
в случае ошибки, и помещает размер буфера вto_length
. Результат должен быть освобожден с помощьюPQfreemem
, когда он больше не нужен.Это преобразование не является точной обратной операцией для
PQescapeBytea
, потому что строка не ожидается быть “экранированной” при получении изPQgetvalue
. В частности, это означает, что нет необходимости учитывать экранирование строк, и, следовательно, нет необходимости в параметреPGconn
.