pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
与数据库服务器的连接成功建立后,此处描述的函数用于执行 SQL 查询和命令。
PQexec #提交一个命令给服务器并且等待结果。
PGresult *PQexec(PGconn *conn, const char *command);
返回一个PGresult指针或者可能是一个空指针。除了内存不足或严重错误(例如无法将命令发送到服务器)之外,通常都会返回非空指针。如果返回了空指针,应把它当作一个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相似,但是提供了额外的功能:参数值可以与命令字符串分开指定,并且可以以文本或二进制格式请求查询结果。 PQexecParams 仅支持使用协议 3.0 及更高版本的连接;使用协议 2.0 时会失败。
该函数的参数是:
conn要在其中发送命令的连接对象。
command要执行的 SQL 命令字符串。如果使用了参数,它们在该命令字符串中被引用为$1、$2等。
nParams提供的参数数量。它是数组paramTypes[]、paramValues[]、paramLengths[]和paramFormats[]的长度(当nParams为零时,数组指针可以是NULL)。
paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。如果paramTypes为NULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。
paramValues[]指定参数的实际值。数组中的空指针表示对应参数为 null;否则,指针指向以零结尾的文本字符串(文本格式),或采用服务器所要求格式的二进制数据(二进制格式)。
paramLengths[]指定二进制格式参数的实际数据长度。对于 null 参数和文本格式参数,该值会被忽略。如果没有二进制参数,数组指针可以为空指针。
paramFormats[]指定参数采用文本格式(在对应数组元素中填入零)还是二进制格式(填入一)。如果数组指针为空指针,则将所有参数视为文本字符串。
以二进制格式传递值时,需要了解后端所要求的内部表示形式。例如,整数必须以网络字节序传递。传递 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 值写死在程序中时。不过,即使服务器无法自行确定参数类型,或者推断出的类型与你所需的不同,也可以避免直接指定 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 执行。此功能允许将被反复使用的命令只解析和规划一次,而不是每次执行时都重复进行。PQprepare 仅在使用协议 3.0 及更高版本的连接中受支持,使用协议 2.0 时会失败。
该函数从query串创建一个名为stmtName的预备语句,该串必须包含一个单一 SQL 命令。 stmtName可以是""来创建一个未命名语句,在这种情况下任何已存在未命名语句将被自动替换。 否则,如果语句名称已经在当前会话中被定义,则是一种错误。如果使用了任何参数,它们在查询中以$1、$2等引用。 nParams 是在数组 paramTypes[] 中预先指定了类型的参数数量(当nParams为零时,该数组指针可以是NULL)。 paramTypes[]通过 OID 指定要赋予给参数符号的数据类型。 如果paramTypes是NULL或者该数组中任何特定元素为零,服务器会用对待未指定类型的字符串字面量的方式为参数符号推测一种数据类型。 还有,查询能够使用编号高于nParams的参数符号,它们的数据类型也会被自动推测(找出推测出的数据类型的方法见PQdescribePrepared)。
正如PQexec一样,结果通常是一个PGresult对象,其内容代表服务器端成功或失败。 返回空指针表示内存不足,或者根本无法发送命令。关于错误的更多信息请见PQerrorMessage。
用于PQexecPrepared的预备语句也可以通过执行 SQLPREPARE语句来创建。此外,虽然没有libpq函数可删除预备语句,但可以使用 SQLDEALLOCATE语句来完成。
PQexecPrepared #发送一个请求来执行一个带有给定参数的预备语句,并等待结果。
PGresult *PQexecPrepared(PGconn *conn,
const char *stmtName,
int nParams,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
PQexecPrepared类似于PQexecParams, 但它通过已创建的预备语句的名称指定要执行的命令,而非提供查询字符串。 此功能使重复使用的命令只需解析和规划一次,而不必在每次执行时都进行这些工作。 该语句必须事先在当前会话中创建为预备语句。 PQexecPrepared 仅支持使用协议 3.0 及更高版本的连接;使用协议 2.0 时会失败。
参数与PQexecParams相同,只是给出了预备语句的名称而不是查询字符串, 并且paramTypes[]参数不存在(因为在创建预备语句时已确定了参数类型)。
PQdescribePrepared #提交请求以获取有关指定预备语句的信息,并等待完成。
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
PQdescribePrepared允许应用程序获取关于先前创建的预备语句的信息。 PQdescribePrepared 仅支持使用协议 3.0 及更高版本的连接;使用协议 2.0 时会失败。
stmtName可以是""或NULL来引用 未命名的语句,否则必须是现有预备语句的名称。成功时,返回一个 状态为PGRES_COMMAND_OK的PGresult。 函数PQnparams和 PQparamtype可以应用于此 PGresult以获取有关预备语句参数的信息, 函数PQnfields、PQfname、 PQftype等提供有关语句的结果列(如果有)的信息。
PQdescribePortal #提交请求以获取有关指定 portal 的信息,并等待完成。
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortal 允许应用程序获取先前创建的 portal 的信息。(libpq 不提供对 portal 的直接访问,但可以用此函数检查通过 DECLARE CURSOR SQL 命令创建的游标的属性。) PQdescribePortal 仅支持使用协议 3.0 及更高版本的连接;使用协议 2.0 时会失败。
portalName可以是""或NULL来引用未命名的 portal, 否则必须是现有 portal 的名称。成功时,将返回一个带有状态PGRES_COMMAND_OK的PGresult。 函数PQnfields、PQfname、PQftype等可应用于 PGresult,以获取有关 portal 的结果列(如果有)的信息。
PGresult结构封装了服务器返回的结果。libpq应用程序员应该小心地维护PGresult的抽象。使用下面的访问器函数来获取PGresult的内容。避免直接引用PGresult结构的字段,因为它们在未来可能会改变。
PQresultStatus #返回该命令的结果状态。
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatus可以返回下列值之一:
如果结果状态是PGRES_TUPLES_OK,那么可以使用下面描述的函数来检索查询返回的行。注意,一个恰好检索到零行的SELECT命令仍然显示为PGRES_TUPLES_OK。PGRES_COMMAND_OK用于永远不会返回行的命令(INSERT、UPDATE等)。一个PGRES_EMPTY_QUERY响应可能表示客户端软件中的一个 bug。
一个状态为PGRES_NONFATAL_ERROR的结果将不会被PQexec或者其他查询执行函数直接返回,这类结果将被传递给提示处理器(见 第 31.11 节)。
PQresStatus #将 PQresultStatus 返回的枚举值转换为描述该状态码的字符串常量。调用者不应释放此结果。
char *PQresStatus(ExecStatusType status);
PQresultErrorMessage #返回与命令关联的错误消息;如果没有错误,则返回空字符串。
char *PQresultErrorMessage(const PGresult *res);
如果发生了错误,返回的字符串会以换行符结尾。调用者不应直接释放结果;当关联的 PGresult 句柄被传给 PQclear 时,结果会被释放。
紧跟着一个PQexec 或 PQgetResult调用,PQerrorMessage(在连接上)将返回与PQresultErrorMessage相同的字符串(在结果上)。 不过,一个PGresult将保持它的错误消息直到被销毁,而连接的错误消息将在后续操作被执行时被更改。 当你想要知道与一个特定PGresult相关的状态,使用PQresultErrorMessage。 而当你想要知道连接上最后一个操作的状态,使用PQerrorMessage。
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_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 #一个失败的内部产生的命令的文本。例如,这可能是由一个 PL/pgSQL 函数发出的 SQL 查询。
PG_DIAG_CONTEXT #指示错误发生的上下文。当前这包括活动过程语言函数的调用栈追踪以及内部生成的查询。追踪是每行一项,最近的排在最前面。
PG_DIAG_SOURCE_FILE #报告错误的源代码所在的文件名。
PG_DIAG_SOURCE_LINE #报告错误的源代码行号。
PG_DIAG_SOURCE_FUNCTION #报告错误的源代码函数的名字。
客户端负责按自身需要格式化所显示的信息,尤其应在需要时将长行折行。错误消息字段中的换行符应当视为段落分隔,而非行分隔。
libpq 内部产生的错误包含严重性和主要消息,但通常没有其他字段。使用 3.0 之前协议的服务器返回的错误包含严重性和主要消息,有时还包含详细消息,但没有其他字段。
注意,错误字段只对PGresult对象有效,对PGconn对象无效。没有PQerrorField函数。
PQclear #释放与 PGresult 关联的存储空间。每个命令结果在不再需要时都应通过 PQclear 释放。
void PQclear(PGresult *res);
你可以在需要时一直保留PGresult对象;它不会在你发出新命令时消失,甚至在关闭连接后也不会消失。要销毁它,你必须调用PQclear。否则应用程序会发生内存泄漏。
这些函数用于从表示成功查询结果的PGresult对象(即状态为PGRES_TUPLES_OK的对象)中提取信息。它们也可用于提取成功 Describe 操作的结果信息:Describe 结果包含的列信息与实际执行查询时相同,但行数为零。对于其他状态值的对象,这些函数会将结果视为零行、零列。
PQntuples #返回查询结果中的行(元组)数。因为它返回一个整数结果,在 32 位操作系统上大的结果集可能会导致返回值溢出。
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);
如果列号超出范围、指定的列不是对表列的简单引用,或者使用 3.0 之前的协议,则返回 InvalidOid。可以查询系统表 pg_class,确定所引用的具体表。
包含 libpq 头文件后,将定义类型 Oid 和常量 InvalidOid。它们都属于某种整数类型。
PQftablecol #返回指定查询结果列所对应的表列在表中的列号。查询结果的列号从 0 开始,而表列的编号非零。
int PQftablecol(const PGresult *res,
int column_number);
如果列号超出范围、指定的列不是对表列的简单引用,或者使用 3.0 之前的协议,则返回零。
PQfformat #返回表示给定列格式的格式代码。列号从 0 开始。
int PQfformat(const PGresult *res,
int column_number);
格式代码零表示文本数据,格式代码一表示二进制数据。(其他代码保留供将来定义。)
PQftype #返回与给定列号相关联的数据类型。被返回的整数是该类型的内部 OID 号。列号从 0 开始。
Oid PQftype(const PGresult *res,
int column_number);
可以查询系统表 pg_type 来获取各种数据类型的名称和属性。内置数据类型的 OID 定义在源码树的 src/include/catalog/pg_type.h 文件中。
PQfmod #返回与给定列号相关联的列的类型修饰符。列号从 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 #返回 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);
如果字段为 null,此函数返回 1;如果包含非 null 值,则返回 0。(注意,对于 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 #返回来自于产生PGresult的 SQL 命令的命令状态标签。
char *PQcmdStatus(PGresult *res);
通常这就是该命令的名称,但是它可能包括额外数据,例如已被处理的行数。调用者不应该直接释放该结果。它将在相关的PGresult句柄被传递给PQclear之后被释放。
PQcmdTuples #返回受该 SQL 命令影响的行数。
char *PQcmdTuples(PGresult *res);
此函数返回一个字符串,其中包含产生该 PGresult 的 SQL 语句所影响的行数。此函数只能在执行 SELECT、CREATE TABLE AS、INSERT、UPDATE、DELETE、MOVE、FETCH 或 COPY 语句之后使用,也可以在对包含 INSERT、UPDATE 或 DELETE 语句的预备查询执行 EXECUTE 之后使用。如果产生 PGresult 的是其他命令,PQcmdTuples 将返回空字符串。调用者不应直接释放返回值;当关联的 PGresult 句柄被传给 PQclear 时,返回值会被释放。
PQoidValue #如果该SQL命令是一个正好将一行插入到具有 OID 的表的INSERT,或者是一个包含合适INSERT语句的预备查询的EXECUTE,这个函数返回被插入行的 OID。否则,这个函数返回InvalidOid。如果被INSERT语句影响的表不包含 OID,这个函数也将返回InvalidOid。
Oid PQoidValue(const PGresult *res);
PQoidStatus #如果该SQL命令是一个恰好插入一行的INSERT,或者是一个由合适的INSERT构成的预备语句的EXECUTE,返回一个带有被插入行 OID 的字符串。(如果INSERT没有恰好插入一行,或者目标表没有 OID,该字符串将为0。)如果该命令不是一个INSERT,返回一个空字符串。
char *PQoidStatus(const PGresult *res);
此函数已被弃用,推荐使用PQoidValue。它不是线程安全的。
PQescapeLiteral #char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
为了让一个字符串可用于 SQL 命令,PQescapeLiteral会对它进行转义。 当在 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使用十六进制编码或反斜杠转义来转义这些字节。详见第 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参数指向一个字符串,例如对bytea列调用PQgetvalue时返回的字符串。 PQunescapeBytea将这个字符串表示转换为二进制表示。 它返回指向通过malloc()分配的缓冲区的指针,出错时返回NULL,并将缓冲区大小存入to_length。 不再需要结果时,必须使用PQfreemem释放它。
此转换并不完全是PQescapeBytea的逆操作,因为从PQgetvalue收到的字符串并非经过“转义”的形式。 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。