一旦到数据库服务器的连接被成功建立, 这里描述的函数就会被用于执行 SQL 查询和命令。
PQexec #向服务器提交命令并同步阻塞等待直至返回查询结果。
PGresult *PQexec(PGconn *conn, const char *command);
返回指向 PGresult 结果对象的指针,或在极端异常时返回空指针。除了系统物理内存耗尽(OOM)或无法向服务器发送命令等严重底层错误外,通常都会返回一个非空的对象指针。应当始终调用 PQresultStatus 函数检查返回值以核验是否存在错误(若传入空指针,该函数会安全返回 PGRES_FATAL_ERROR)。可以使用
PQerrorMessage
获取关于该错误的详细文本信息。
命令字符串可以包含多条 SQL 命令
(以分号分隔)。
在单次
PQexec
调用中发送的多条查询会在单个事务中被处理,
除非查询字符串中包含显式的
BEGIN/COMMIT
命令把它划分为多个事务。
(关于服务器如何处理多查询字符串的更多细节,
请参见
Section 54.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,但提供了更强大的高级特性:参数值可以与 SQL 命令字符串本身严格分离传递,并且可以请求以文本或二进制格式接收查询结果。
The function arguments are:
conn用于发送 SQL 命令的数据库物理连接对象。
command
要执行的 SQL 命令字符串。如果使用了参数,在命令字符串中按 $1、$2 等占位符进行引用。
nParams
提供的参数数量;它对应数组 paramTypes[]、paramValues[]、paramLengths[] 和 paramFormats[] 的长度(当 nParams 为 0 时,这些数组指针可以为 NULL)。
paramTypes[]
通过类型 OID 指定赋予各参数符号的数据类型。如果 paramTypes 为 NULL,或者数组中的某个特定元素为 0,服务端会像处理无类型的普通文本字面量一样自动推断该参数的数据类型。
paramValues[]指定参数的实际数值。数组中的 NULL 空指针表示对应参数为 SQL NULL 值;否则该指针指向以 null 结尾的文本字符串(用于文本格式)或符合服务端预期格式的二进制数据(用于二进制格式)。
paramLengths[]指定二进制格式参数的实际数据字节长度。对于 NULL 参数和文本格式参数,该长度会被自动忽略。当没有二进制参数时,该数组指针可以为 NULL。
paramFormats[]指定参数采用文本格式(在对应数组元素中填 0)还是二进制格式(填 1)。如果该数组指针为 NULL,则默认所有参数均为文本字符串格式。
以二进制格式传递数值需要了解后端内核所期望的内部表示形式。例如整数必须以网络字节序(大端序)传递;传递 numeric 类型数值需要了解服务端的存储布局(如源码 src/backend/utils/adt/numeric.c 中的实现)。
resultFormat指定为 0 表示以文本格式接收查询结果,指定为 1 表示以二进制格式接收结果(目前 API 层面不支持不同列采用不同格式,尽管底层前端/后端通信协议具备该能力)。
PQexecParams 相比 PQexec 的核心优势在于参数值与 SQL 命令文本分离传递,从而彻底消除了繁琐且极易引入安全漏洞的单引号转义拼接,天然免疫 SQL 注入。
与 PQexec 不同,PQexecParams 在给定字符串中至多允许包含一条 SQL 命令(可以包含分号,但不能超过一条非空命令)。这是底层扩展查询协议的固有规范,但也为防范 SQL 注入攻击提供了额外的安全防护墙。
通过 OID 指定参数类型很麻烦, 特别是当你不希望把特定的 OID 值硬编码进程序时。 然而,即便在服务器自己无法确定参数的类型, 或选择了与你想要的不同类型的情况下, 你也可以避免那样做。 在 SQL 命令文本中, 给参数符号附上一个显式的类型转换, 以表明你将发送的数据类型。 例如:
SELECT * FROM mytable WHERE x = $1::bigint;
这会强制参数 $1
被当作 bigint 处理,
而默认情况下它会被赋予与
x
相同的类型。
在以二进制格式发送参数值时,
强烈建议用这种方式或通过指定数字类型 OID
来强制参数类型的决定,
因为二进制格式的冗余比文本格式少,
因此服务器为你检测到类型不匹配错误的机会也更小。
PQprepare #提交创建指定参数的预备语句(Prepared Statement)请求并同步等待完成。
PGresult *PQprepare(PGconn *conn,
const char *stmtName,
const char *query,
int nParams,
const Oid *paramTypes);
PQprepare
创建一个已准备语句,
供以后用
PQexecPrepared
执行。
这个特性允许命令被重复执行而无需每次都被解析和计划;
细节请参见 PREPARE。
该函数从 query
字符串创建一个名为
stmtName
的已准备语句,
该字符串必须包含单个 SQL 命令。
stmtName
可以为 ""
以创建一个未命名语句,
在这种情况下任何预先存在的未命名语句都会被自动替换;
否则,如果该语句名已在当前会话中被定义,
则是一个错误。
如果使用了任何参数,
它们在查询中被称为
$1、$2
等。
nParams
是在数组
paramTypes[]
中预先指定了类型的参数的数量。
(当 nParams
为零时,
数组指针可以为
NULL。)
paramTypes[]
通过 OID 指定要赋予参数符号的数据类型。
如果 paramTypes
为 NULL,
或数组中的任何特定元素为零,
服务器会按照它对待一个无类型字面量字符串的方式为参数符号
分配数据类型。
此外,
查询可以使用编号高于
nParams
的参数符号;
这些符号的数据类型也会被推断出来。
(有关查明推断出了什么数据类型的方法,
请参见
PQdescribePrepared。)
与 PQexec 相同,返回结果通常是指示服务端成功或失败的 PGresult 对象。返回空指针表示物理内存不足或无法发送命令。可以使用
PQerrorMessage
获取关于错误的详细信息。
供 PQexecPrepared
使用的已准备语句也可以通过执行 SQL 的
PREPARE
语句来创建。
PQexecPrepared #发送使用给定参数执行指定预备语句的请求,并同步等待执行结果。
PGresult *PQexecPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
PQexecPrepared 类似于 PQexecParams,但要执行的命令是通过指定先前已准备好的预备语句名称来指定的,而非提供 SQL 查询字符串。该特性允许将反复重复执行的命令仅执行一次语法解析和生成查询计划,而在后续每次执行时直接复用。该预备语句必须在当前会话中事先已准备就绪。
这些参数与
PQexecParams
相同,
除了给出的是一个已准备语句的名字而非查询字符串,
并且 paramTypes[]
参数不存在
(由于已准备语句的参数类型在它被创建时已经确定,
所以不需要它)。
PQdescribePrepared #提交获取指定预备语句元数据信息的请求,并同步等待完成。
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
PQdescribePrepared
允许应用程序获得关于一个先前准备的已准备语句的信息。
stmtName
可以为 "" 或
NULL
来引用未命名语句,
否则它必须是一个现有已准备语句的名字。
成功时,
返回一个状态为
PGRES_COMMAND_OK
的 PGresult。
函数 PQnparams 和
PQparamtype
可以应用于这个
PGresult
来获得关于已准备语句参数的信息,
而函数
PQnfields、
PQfname、
PQftype
等提供关于该语句结果列(如果有)的信息。
PQdescribePortal #提交获取指定游标门(Portal)元数据信息的请求,并同步等待完成。
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortal
允许应用程序获得关于一个先前创建的游标的信息。
(libpq
不提供对游标的任何直接访问,
但你可以使用这个函数来检查用
DECLARE CURSOR
SQL 命令创建的游标的属性。)
portalName
可以为 "" 或
NULL
来引用未命名游标,
否则它必须是一个现有游标的名字。
成功时,
返回一个状态为
PGRES_COMMAND_OK
的 PGresult。
函数
PQnfields、
PQfname、
PQftype
等可以应用于该
PGresult
来获得关于该游标结果列(如果有)的信息。
PQclosePrepared #提交关闭指定预备语句的请求,并同步等待完成。
PGresult *PQclosePrepared(PGconn *conn, const char *stmtName);
PQclosePrepared 允许应用程序显式关闭先前创建的预备语句。关闭预备语句将释放服务端占用的所有相关内存和计划缓存资源,并允许其名称被后续重新使用。
stmtName
可以为 "" 或
NULL
来引用未命名语句。
如果不存在具有该名字的语句也没有关系,
在这种情况下该操作是一个空操作。
成功时,
返回一个状态为
PGRES_COMMAND_OK
的 PGresult。
PQclosePortal #提交关闭指定游标门(Portal)的请求,并同步等待完成。
PGresult *PQclosePortal(PGconn *conn, const char *portalName);
PQclosePortal
允许应用程序触发对一个先前创建的游标的关闭。
关闭一个游标会释放它在服务器上的所有相关资源,
并允许它的名字被复用。
(libpq
不提供对游标的任何直接访问,
但你可以使用这个函数来关闭一个用
DECLARE CURSOR
SQL 命令创建的游标。)
portalName
可以为 "" 或
NULL
来引用未命名游标。
如果不存在具有该名字的游标也没有关系,
在这种情况下该操作是一个空操作。
成功时,
返回一个状态为
PGRES_COMMAND_OK
的 PGresult。
PGresult
结构封装了服务器返回的结果。
libpq
应用程序开发者应当小心地维持
PGresult
的抽象。
使用下面的访问器函数来获取
PGresult
的内容。
避免直接引用
PGresult
结构的字段,
因为它们在将来可能发生变化。
PQresultStatus #返回命令执行的结果状态码。
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatus
可以返回以下值之一:
PGRES_EMPTY_QUERY #发送给服务器的字符串为空。
PGRES_COMMAND_OK #不返回数据行的命令(如 INSERT、UPDATE、DELETE 或 DDL)成功执行完毕。
PGRES_TUPLES_OK #
返回数据行的查询命令(如 SELECT 或 SHOW)成功执行完毕。
PGRES_COPY_OUT #从服务端导出数据的 Copy Out 数据传输流程已启动。
PGRES_COPY_IN #向服务端导入数据的 Copy In 数据传输流程已启动。
PGRES_BAD_RESPONSE #无法识别或解析服务端的响应报文。
PGRES_NONFATAL_ERROR #发生了非致命通知或警告错误(NOTICE 或 WARNING)。
PGRES_FATAL_ERROR #发生了致命执行错误(SQL 命令执行失败)。
PGRES_COPY_BOTH #双向 Copy In/Out 数据传输流程已启动(目前仅用于流复制,常规业务应用不会遇到)。
PGRES_SINGLE_TUPLE #
PGresult 仅包含来自当前查询的单条数据行。此状态仅在为查询启用了单行模式时出现(参见 Section 32.6)。
PGRES_TUPLES_CHUNK #
PGresult 包含来自当前查询的若干数据行(数据分块)。此状态仅在为查询启用了分块模式时出现(参见 Section 32.6)。元组行数不会超过传递给 PQsetChunkedRowsMode 的上限。
PGRES_PIPELINE_SYNC #
这个
PGresult
表示管道模式中的一个同步点,
它由
PQpipelineSync 或
PQsendPipelineSync
请求。
只有当选择了管道模式时才会出现这个状态。
PGRES_PIPELINE_ABORTED #
这个
PGresult
表示一个已从服务器收到错误的管道。
PQgetResult
必须被反复调用,
并且每次它都会返回这个状态码,
直到当前管道结束,
在那时它将返回
PGRES_PIPELINE_SYNC,
并且可以恢复正常处理。
如果结果状态是
PGRES_TUPLES_OK、
PGRES_SINGLE_TUPLE 或
PGRES_TUPLES_CHUNK,
那么可以用下面描述的函数来检索该查询返回的行。
注意,一条恰好检索到零行的
SELECT
命令仍然显示
PGRES_TUPLES_OK。
PGRES_COMMAND_OK
用于那些永远不返回行的命令
(例如不带
RETURNING
子句的
INSERT 或
UPDATE)。
一个
PGRES_EMPTY_QUERY
响应可能表明客户端软件中存在缺陷。
状态为
PGRES_NONFATAL_ERROR
的结果永远不会由
PQexec
或其他查询执行函数直接返回;
这类结果会被传递给通知处理器
(参见
Section 32.13)。
PQresStatus #
将由 PQresultStatus 返回的枚举类型状态码转换为描述该状态码的静态字符串常量。调用者切勿释放该返回结果。
char *PQresStatus(ExecStatusType status);
PQresultErrorMessage #返回与该命令关联的错误消息, 如果没有错误则返回一个空字符串。
char *PQresultErrorMessage(const PGresult *res);
如果有错误,
返回的字符串将包括一个结尾的换行符。
调用者不应当直接释放该结果。
当相关的
PGresult
句柄被传递给
PQclear
时它会被释放。
紧跟在 PQexec 或
PQgetResult
调用之后,
(连接上的)
PQerrorMessage
将返回与
(结果上的)
PQresultErrorMessage
相同的字符串。
然而,
一个
PGresult
会保留它的错误消息直到被销毁,
而连接的错误消息会在后续操作完成时改变。
当你想知道与一个特定
PGresult
关联的状态时,
使用
PQresultErrorMessage;
当你想知道连接上最新操作的状态时,
使用
PQerrorMessage
。
PQresultVerboseErrorMessage #
返回与一个
PGresult
对象关联的错误消息的重新格式化版本。
char *PQresultVerboseErrorMessage(const PGresult *res,
PGVerbosity verbosity,
PGContextVisibility show_context);
在某些情况下,
客户端可能希望获得先前报告错误的更详细版本。
PQresultVerboseErrorMessage
满足了这一需求,
它计算的内容是:如果在生成给定的
PGresult
时该连接的详细程度设置是这里指定的那些,
PQresultErrorMessage
本来会产生的消息。
如果该
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
字段相同,
只是内容永远不会被本地化。
它只出现在由
PostgreSQL
版本 9.6 及更高版本生成的报告中。
PG_DIAG_SQLSTATE #该错误的 SQLSTATE 码。 SQLSTATE 码标识已发生的错误类型; 前端应用程序可以用它来执行特定操作 (例如错误处理) 以响应某个特定的数据库错误。 可能的 SQLSTATE 码列表请参见 Appendix 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 #一条失败的内部生成命令的文本。 例如, 它可能是由一个 PL/pgSQL 函数发出的一条 SQL 查询。
PG_DIAG_CONTEXT #错误发生时所处的上下文的指示。 目前这包括活动的 procedural language 函数和内部生成查询的调用栈回溯。 回溯每行一个条目, 最近的在最前。
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 #报告错误的源代码函数的名字。
模式名、表名、列名、数据类型名和约束名字段只在有限数量的 错误类型中提供; 参见 Appendix A。 不要假定其中任何一个字段的存在保证了另一个字段的存在。 核心错误源遵循上述的相互关系, 但用户定义的函数可能以其他方式使用这些字段。 同样地, 不要假定这些字段表示当前数据库中的当代对象。
客户端负责把显示的信息格式化为满足其需要的形式; 特别是它应当根据需要折断长行。 出现在错误消息字段中的换行字符应当被视为段落分隔, 而非换行。
由 libpq 内部生成的错误将具有严重级别和主消息, 但通常没有其他字段。
注意,错误字段只在
PGresult
对象上可用,
在
PGconn
对象上不可用;
不存在
PQerrorField 函数。
PQclear #
释放与 PGresult 对象关联的所有物理内存空间。在命令执行结果不再需要时,必须通过 PQclear 将其释放。
void PQclear(PGresult *res);
若传入的实参是 NULL 空指针,则不执行任何操作。
您可以根据需要持有 PGresult 对象任意长的时间;即使您发起了新的 SQL 命令,甚至关闭了底层数据库物理连接,该结果对象依然安全存在于客户端内存中。要彻底销毁它,必须显式调用 PQclear。若不调用此函数,将导致客户端应用程序发生严重的内存泄漏。
这些函数用于从代表成功查询结果的 PGresult 对象(即状态为 PGRES_TUPLES_OK、PGRES_SINGLE_TUPLE 或 PGRES_TUPLES_CHUNK 的对象)中提取查询数据和元数据信息。它们同样可以用于从成功的 Describe 操作中提取元数据:Describe 返回的结果具有与实际执行查询相同的列结构元数据,只是行数为 0。对于具有其他状态值的对象,这些函数的行为如同结果集为 0 行 0 列。
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 以准确确定所引用的物理表。
包含 libpq 头文件时会自动定义 Oid 类型及常量 InvalidOid(二者均为整数类型)。
PQftablecol #返回构成指定查询结果列的列在源表内部的列属性编号(attribute number)。查询结果列编号从 0 开始计数,而表内部列编号为非零正整数。
int PQftablecol(const PGresult *res,
int column_number);
若列编号越界,或者指定列不是对表列的简单直接引用,则返回 0。
PQfformat #返回指示指定列格式的格式代码。列编号从 0 开始计数。
int PQfformat(const PGresult *res,
int column_number);
格式代码 0 表示文本数据格式,格式代码 1 表示二进制格式(其他代码保留供未来定义)。
PQftype #返回与指定列编号相关联的数据类型的内部 OID 标识符。列编号从 0 开始计数。
Oid PQftype(const PGresult *res,
int column_number);
您可以查询系统表 pg_type 获取各种数据类型的名称与元数据。内置基础数据类型的 OID 常量定义在安装目录下的 include/catalog/pg_type_d.h 头文件中。
PQfmod #返回与指定列编号相关联的类型修饰符(typmod)。列编号从 0 开始计数。
int PQfmod(const PGresult *res,
int column_number);
类型修饰符的含义取决于具体数据类型,通常用于指示精度、标度或长度限制。数值 -1 表示“无可用修饰符信息”。大多数数据类型不使用修饰符,此时返回值始终为 -1。
PQfsize #返回与指定列编号相关联的列在服务器内部的固定字节大小。列编号从 0 开始计数。
int PQfsize(const PGresult *res,
int column_number);
PQfsize
返回数据库行中为这个列分配的空间,
换句话说,
即服务器对该数据类型的内部表示的大小。
(因此,它对客户端来说并不是很有用。)
一个负值表示该数据类型是变长的。
PQbinaryTuples #
如果该
PGresult
包含二进制数据则返回 1,
如果它包含文本数据则返回 0。
int PQbinaryTuples(const PGresult *res);
这个函数已被弃用
(除了与
COPY
一起使用的情况),
因为单个
PGresult
有可能在某些列中包含文本数据,
而在其他列中包含二进制数据。
首选 PQfformat。
只有当结果的所有列都是二进制(格式 1)时,
PQbinaryTuples
才返回 1。
PQgetvalue #
提取指定行号与列号单元格的数据值。行号与列号均从 0 开始计数。调用者切勿直接释放该返回指针;它会在关联的 PGresult 句柄被传递给 PQclear 时自动回收。
char *PQgetvalue(const PGresult *res,
int row_number,
int column_number);
对于文本格式的数据,PQgetvalue 返回的值是以空字符(null)结尾的字符文本表示。对于二进制格式的数据,该值是由数据类型的 typsend 和 typreceive 函数确定的二进制内部格式(在此情况下末尾同样追加了一个零字节,但由于二进制数据本身可能包含内嵌空字符,因此必须结合长度使用)。
若字段值为 SQL NULL,该函数将返回空字符串 ""。请务必使用 PQgetisnull 来严格区分 SQL NULL 空值与字面量空字符串。
由 PQgetvalue 返回的指针直接指向属于 PGresult 结构体内部的内存区。调用者不得修改其指向的数据;若要在 PGresult 对象释放后继续使用该数据,必须显式将其深拷贝到独立内存中。
PQgetisnull #测试指定行号与列号单元格是否为 SQL NULL 空值。行号与列号均从 0 开始计数。
int PQgetisnull(const PGresult *res,
int row_number,
int column_number);
如果该字段为 NULL 则返回 1,若包含非空值则返回 0(注意:对于 NULL 字段,PQgetvalue 会返回空字符串而非 NULL 空指针)。
PQgetlength #返回字段数据值的实际字节长度。行号与列号均从 0 开始计数。
int PQgetlength(const PGresult *res,
int row_number,
int column_number);
这是特定数据值的实际物理字节长度,即 PQgetvalue 所指向的数据大小。对于文本数据格式,该值等价于 strlen()。对于二进制格式,这是至关重要的长度信息。请注意,切勿依赖 PQfsize 来获取实际数据长度。
PQnparams #返回预备语句的形参参数数量。
int PQnparams(const PGresult *res);
该函数仅在检查 PQdescribePrepared 的返回结果时有用;对于其他类型的结果,它将直接返回 0。
PQparamtype #返回指定预备语句参数的数据类型 OID。参数编号从 0 开始计数。
Oid PQparamtype(const PGresult *res, int param_number);
该函数仅在检查 PQdescribePrepared 的返回结果时有用;对于其他类型的结果,它将直接返回 0。
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 用来打印查询结果, 但现在不再如此。 注意,它假定所有数据都是文本格式。
这些函数用于从
PGresult
对象提取其他信息。
PQcmdStatus #
返回产生该
PGresult
的 SQL 命令的命令状态标签。
char *PQcmdStatus(PGresult *res);
通常这就是命令的名字,
但它可能包括额外的数据,
例如被处理的行数。
调用者不应当直接释放该结果。
当相关的
PGresult
句柄被传递给
PQclear
时它会被释放。
PQcmdTuples #返回受该 SQL 命令影响的行数。
char *PQcmdTuples(PGresult *res);
这个函数返回一个字符串,
其中包含受产生该
PGresult
的 SQL
语句影响的行数。
这个函数只能在执行了一条
SELECT、
CREATE TABLE AS、
INSERT、
UPDATE、
DELETE、
MERGE、
MOVE、
FETCH
或 COPY
语句,
或者执行了一个包含
INSERT、
UPDATE、
DELETE
或 MERGE
语句的已准备查询的
EXECUTE
之后使用。
如果产生该
PGresult
的命令是其他任何命令,
PQcmdTuples
会返回一个空字符串。
调用者不应当直接释放返回值。
当相关的
PGresult
句柄被传递给
PQclear
时它会被释放。
PQoidValue #
如果该
SQL
命令是一条向一个拥有 OID
的表中恰好插入了一行的
INSERT,
或者是包含一条适当的
INSERT
语句的已准备查询的
EXECUTE,
则返回被插入行的
OID。
否则,这个函数返回
InvalidOid。
如果受
INSERT
语句影响的表不包含 OID,
这个函数也会返回
InvalidOid。
Oid PQoidValue(const PGresult *res);
PQoidStatus #
这个函数已被弃用,
应改用
PQoidValue,
并且它不是线程安全的。
它返回一个包含被插入行 OID
的字符串,
而
PQoidValue
返回 OID 值。
char *PQoidStatus(const PGresult *res);
PQescapeLiteral #
char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
PQescapeLiteral
对一个字符串进行转义,
以便在 SQL 命令中使用。
当把数据值作为字面常量插入 SQL
命令时,
这很有用。
某些字符(例如引号和反斜杠)
必须被转义,
以防止它们被 SQL
解析器特殊解释。
PQescapeLiteral
执行这个操作。
PQescapeLiteral
返回
str
参数的一个转义版本,
所用内存由
malloc()
分配。
当不再需要结果时,
这块内存应当用
PQfreemem()
释放。
不需要结尾的零字节,
并且不应当把它计入
length。
(如果在处理完
length
字节之前发现了一个结尾零字节,
PQescapeLiteral
会在零处停止;
因此这种行为相当类似于
strncpy。)
返回的字符串中所有特殊字符都被替换,
使它们能够被
PostgreSQL
的字符串字面量解析器正确处理。
也会添加一个结尾的零字节。
必须环绕
PostgreSQL
字符串字面量的单引号包含在结果字符串中。
出错时,
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
不会产生必须环绕
PostgreSQL
字符串字面量的单引号;
它们应当在结果被插入到的 SQL
命令中提供。
参数 from
指向要转义的字符串的第一个字符,
length
参数给出这个字符串的字节数。
不需要结尾的零字节,
并且不应当把它计入
length。
(如果在处理完
length
字节之前发现了一个结尾零字节,
PQescapeStringConn
会在零处停止;
因此这种行为相当类似于
strncpy。)
to
应当指向一个至少能容纳
length
值的两倍再多一个字节的缓冲区,
否则行为是未定义的。
如果 to
和 from
字符串重叠,
行为同样未定义。
如果 error
参数不是 NULL,
那么成功时
*error
被设置为零,
出错时为非零。
目前唯一可能的错误情形是源字符串中存在无效的多字节编码。
出错时输出字符串仍会被生成,
但可以预期服务器会以格式不良为由拒绝它。
出错时,
无论 error
是否为 NULL,
一条合适的消息都会存储在
conn
对象中。
PQescapeStringConn
返回写到
to
的字节数,
不包括结尾的零字节。
PQescapeString #
PQescapeString
是
PQescapeStringConn
的一个较旧的、已弃用的版本。
size_t PQescapeString (char *to, const char *from, size_t length);
与 PQescapeStringConn
的唯一区别是,
PQescapeString
不接受
PGconn
或 error
参数。
正因如此,
它无法根据连接属性(例如字符编码)
调整自己的行为,
因此
它可能给出错误的结果。
此外,
它也没有办法报告错误情况。
PQescapeString
可以在每次只处理一条
PostgreSQL
连接的客户端程序中安全地使用
(在这种情况下它可以在
“幕后”查明它需要知道的东西)。
在其他上下文中它是一个安全隐患,
应当避免使用它而改用
PQescapeStringConn。
PQescapeByteaConn #
对二进制数据进行转义,
以便在 SQL 命令中作为
bytea
类型使用。
与 PQescapeStringConn
一样,
它只用于把数据直接插入到一条 SQL
命令字符串中。
unsigned char *PQescapeByteaConn(PGconn *conn,
const unsigned char *from,
size_t from_length,
size_t *to_length);
某些字节值在作为
SQL
语句中
bytea
字面量的一部分使用时必须被转义。
PQescapeByteaConn
使用十六进制编码或反斜杠转义来转义字节。
更多信息请参见
Section 8.4。
from
参数指向要转义的字符串的第一个字节,
from_length
参数给出这个二进制字符串中的字节数。
(结尾的零字节既不必要也不被计入。)
to_length
参数指向一个将保存得到的转义字符串长度的变量。
这个结果字符串长度包括结果的结尾零字节。
PQescapeByteaConn
返回
from
参数二进制字符串的一个转义版本,
所用内存由
malloc()
分配。
当不再需要结果时,
这块内存应当用
PQfreemem()
释放。
返回的字符串中所有特殊字符都被替换,
使它们能够被
PostgreSQL
的字符串字面量解析器以及
bytea
输入函数正确处理。
也会添加一个结尾的零字节。
必须环绕
PostgreSQL
字符串字面量的单引号不属于结果字符串。
出错时,
返回一个空指针,
并且一条合适的错误消息被存储在
conn
对象中。
目前唯一可能的错误是为结果字符串分配的内存不足。
PQescapeBytea #
PQescapeBytea
是
PQescapeByteaConn
的一个较旧的、已弃用的版本。
unsigned char *PQescapeBytea(const unsigned char *from,
size_t from_length,
size_t *to_length);
与 PQescapeByteaConn
的唯一区别是,
PQescapeBytea
不接受
PGconn
参数。
正因如此,
PQescapeBytea
只能在每次使用一条
PostgreSQL
连接的客户端程序中安全地使用
(在这种情况下它可以在
“幕后”查明它需要知道的东西)。
如果在同时使用多条数据库连接的程序中使用它,
它可能给出错误的结果
(在这样的情况下请使用
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
参数。