On this page
33.3. 命令执行功能
成功构建与数据库服务器的连接后,此处描述的功能将用于执行 SQL 查询和命令。
33 .3.1. 主要功能
PGresult *PQexec(PGconn *conn, const char *command);
返回PGresult
指针或可能为空的指针。通常会返回非空指针,除非在内存不足的情况下或严重错误(例如无法将命令发送到服务器)。应该调用PQresultStatus
函数来检查返回值是否有错误(包括空指针的值,在这种情况下它将返回PGRES_FATAL_ERROR
)。使用PQerrorMessage
获得有关此类错误的更多信息。
命令字符串可以包含多个 SQL 命令(以分号分隔)。除非在查询字符串中包含明确的BEGIN
/COMMIT
命令以将其分为多个事务,否则在单个PQexec
调用中发送的多个查询将在单个事务中处理。但是请注意,返回的PGresult
结构仅描述了从字符串执行的最后一个命令的结果。如果其中一个命令失败,则字符串的处理随之停止,返回的PGresult
描述了错误情况。
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 和更高版本的 Connecting 受支持;使用协议 2.0 时它将失败。
函数参数为:
conn
通过其发送命令的连接对象。
command
- 要执行的 SQL 命令字符串。如果使用了参数,则它们在命令字符串中称为
$1
,$2
等。
- 要执行的 SQL 命令字符串。如果使用了参数,则它们在命令字符串中称为
nParams
- 提供的参数数量;它是数组的长度*
paramTypes[]
,paramValues[]
,paramLengths[]
和paramFormats[]
。 (当nParams
*为零时,数组指针可以为NULL
.)
- 提供的参数数量;它是数组的长度*
paramTypes[]
- 通过 OID 指定要分配给参数符号的数据类型。如果*
paramTypes
*为NULL
,或者数组中的任何特定元素为零,则服务器将以与处理无类型 Literals 字符串相同的方式推断参数符号的数据类型。
- 通过 OID 指定要分配给参数符号的数据类型。如果*
paramValues[]
- 指定参数的实际值。该数组中的空指针表示相应的参数为空;否则,指针将指向以零结尾的文本字符串(对于文本格式)或服务器期望的格式的二进制数据(对于二进制格式)。
paramLengths[]
- 指定二进制格式参数的实际数据长度。对于空参数和文本格式参数,它将被忽略。没有二进制参数时,数组指针可以为 null。
paramFormats[]
- 指定参数是文本(在对应参数的数组条目中 Importing 零)还是二进制(在对应参数的数组条目中 Importing 一)。如果数组指针为 null,则假定所有参数均为文本字符串。
以二进制格式传递的值需要了解后端期望的内部表示形式。例如,必须以网络字节 Sequences 传递整数。传递numeric
值需要了解服务器存储格式,如src/backend/utils/adt/numeric.c::numeric_send()
和src/backend/utils/adt/numeric.c::numeric_recv()
所实现。
resultFormat
- 指定零可获取文本格式的结果,或指定一个可获取二进制格式的结果。 (尽管在底层协议中可能实现,但目前尚无以不同格式获取不同结果列的规定.)
PQexecParams
优于PQexec
的主要优点是可以将参数值与命令字符串分开,从而避免了乏味且容易出错的引号和转义。
与PQexec
不同,PQexecParams
在给定的字符串中最多允许一个 SQL 命令。 (其中可以包含分号,但不能超过一个非空命令.)这是对基础协议的限制,但可以作为对 SQL 注入攻击的额外防御来使用。
Tip
通过 OID 指定参数类型很繁琐,尤其是如果您不想将特定的 OID 值硬连接到程序中时。但是,即使服务器本身无法确定参数的类型或选择与所需类型不同的类型,也可以避免这样做。在 SQL 命令文本中,将显式强制转换附加到参数符号以显示将发送的数据类型。例如:
SELECT * FROM mytable WHERE x = $1::bigint;
这将强制将参数$1
视为bigint
,而默认情况下会将其分配为与x
相同的类型。在以二进制格式发送参数值时,强烈建议通过这种方式或通过指定数字类型 OID 来强制执行参数类型决定,因为二进制格式的冗余度小于文本格式,因此服务器检测类型的可能性较小为您错配错误。
PGresult *PQprepare(PGconn *conn,
const char *stmtName,
const char *query,
int nParams,
const Oid *paramTypes);
PQprepare
创建一个准备好的语句,供以后使用PQexecPrepared
执行。此功能允许重复执行命令,而无需每次都进行解析和计划。有关详情,请参见PREPARE。 PQprepare
仅在协议 3.0 及更高版本的 Connecting 受支持;使用协议 2.0 时它将失败。
该函数从* query
字符串创建一个名为 stmtName
*的准备好的语句,该语句必须包含一个 SQL 命令。 * stmtName
可以是""
以创建未命名的语句,在这种情况下,任何现有的未命名的语句都会被自动替换;否则,如果在当前会话中已经定义了语句名称,则会出现错误。如果使用了任何参数,则它们在查询中称为$1
,$2
等. nParams
是在数组 paramTypes[]
中预先指定类型的参数的数量。 (当 nParams
为零时,数组指针可以为NULL
.) paramTypes[]
通过 OID 指定要分配给参数符号的数据类型。如果 paramTypes
为NULL
,或者数组中的任何特定元素为零,则服务器将其数据类型分配给参数符号,方式与对无类型 Literals 字符串的处理方式相同。此外,查询可以使用数字符号大于 nParams
*的参数符号;这些符号也将推断出数据类型。 (请参见PQdescribePrepared
,以了解推断出哪些数据类型的方法.)
与PQexec
一样,结果通常是PGresult
对象,其内容表示服务器端成功或失败。结果为空表示内存不足或根本无法发送命令。使用PQerrorMessage
获取有关此类错误的更多信息。
也可以通过执行 SQL PREPARE语句来创建供PQexecPrepared
使用的预备语句。同样,尽管没有 libpq 函数可删除准备好的语句,但 SQL DEALLOCATE语句可用于该目的。
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 和更高版本的 Connecting 受支持;使用协议 2.0 时它将失败。
参数与PQexecParams
相同,除了给出的是预准备语句的名称而不是查询字符串,并且不存在* paramTypes[]
*参数(由于创建时准备好的语句的参数类型是确定的,因此不需要此参数) 。
PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
PQdescribePrepared
允许应用程序获取有关先前准备好的语句的信息。 PQdescribePrepared
仅在协议 3.0 和更高版本的 Connecting 受支持;使用协议 2.0 时它将失败。
stmtName
*可以是""
或NULL
来引用未命名的语句,否则它必须是现有准备好的语句的名称。成功时,将返回状态为PGRES_COMMAND_OK
的PGresult
。可以将函数PQnparams
和PQparamtype
应用于此PGresult
以获得有关已准备语句的参数的信息,而函数PQnfields
,PQfname
,PQftype
等提供有关语句的结果列(如果有)的信息。
PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
PQdescribePortal
允许应用程序获取有关先前创建的门户的信息。 (libpq 不提供对门户的任何直接访问,但是您可以使用此功能来检查使用DECLARE CURSOR
SQL 命令创建的游标的属性.)PQdescribePortal
仅在协议 3.0 及更高版本的 Connecting 受支持;使用协议 2.0 时它将失败。
portalName
*可以是""
或NULL
来引用未命名的门户,否则,它必须是现有门户的名称。成功时,将返回状态为PGRES_COMMAND_OK
的PGresult
。可以将功能PQnfields
,PQfname
,PQftype
等应用于PGresult
以获得有关门户的结果列(如果有)的信息。
PGresult
结构封装了服务器返回的结果。 libpq 应用程序程序员应小心维护PGresult
抽象。使用下面的访问器函数获取PGresult
的内容。避免直接引用PGresult
结构的字段,因为它们将来可能会发生变化。
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatus
可以返回以下值之一:
PGRES_EMPTY_QUERY
发送到服务器的字符串为空。
PGRES_COMMAND_OK
- 成功完成命令,不返回任何数据。
PGRES_TUPLES_OK
- 成功完成返回数据的命令(例如
SELECT
或SHOW
)。
- 成功完成返回数据的命令(例如
PGRES_COPY_OUT
- 复制(从服务器)数据传输开始。
PGRES_COPY_IN
- 复制(到服务器)数据传输开始。
PGRES_BAD_RESPONSE
- 无法理解服务器的响应。
PGRES_NONFATAL_ERROR
- 发生非致命错误(通知或警告)。
PGRES_FATAL_ERROR
- 发生致命错误。
PGRES_COPY_BOTH
- 复制进/出(与服务器之间的复制)数据传输开始。此功能当前仅用于流复制,因此在普通应用程序中不应出现此状态。
PGRES_SINGLE_TUPLE
PGresult
包含来自当前命令的单个结果 Tuples。仅当为查询选择单行模式时,才会出现此状态(请参见Section 33.5)。
如果结果状态为PGRES_TUPLES_OK
或PGRES_SINGLE_TUPLE
,则可以使用下面描述的函数来检索查询返回的行。请注意,恰巧检索零行的SELECT
命令仍显示PGRES_TUPLES_OK
。 PGRES_COMMAND_OK
用于永远不会返回行的命令(没有RETURNING
子句的INSERT
或UPDATE
等)。响应PGRES_EMPTY_QUERY
可能表示 Client 端软件中存在错误。
状态PGRES_NONFATAL_ERROR
的结果将永远不会被PQexec
或其他查询执行功能直接返回;此类结果将传递到通知处理器(请参阅Section 33.12)。
char *PQresStatus(ExecStatusType status);
char *PQresultErrorMessage(const PGresult *res);
如果有错误,则返回的字符串将包含尾随换行符。调用方不应直接释放结果。当关联的PGresult
句柄传递到PQclear
时,它将被释放。
紧接PQexec
或PQgetResult
调用之后,PQerrorMessage
(在连接上)将返回与PQresultErrorMessage
(在结果上)相同的字符串。但是,PGresult
将保留其错误消息,直到被销毁,而连接的错误消息将在后续操作完成后更改。当您想了解与特定PGresult
关联的状态时,请使用PQresultErrorMessage
;当您想从连接的最新操作中了解状态时,请使用PQerrorMessage
。
char *PQresultVerboseErrorMessage(const PGresult *res,
PGVerbosity verbosity,
PGContextVisibility show_context);
在某些情况下,Client 可能希望获得以前报告的错误的更详细的版本。 PQresultVerboseErrorMessage
通过计算在生成给定PGresult
时对连接有效的指定详细设置对PQresultErrorMessage
会产生的消息来满足此需求。如果PGresult
不是错误结果,则会报告“ PGresult 不是错误结果”。返回的字符串包括尾随换行符。
与大多数其他用于从PGresult
提取数据的函数不同,此函数的结果是一个新分配的字符串。当不再需要该字符串时,调用者必须使用PQfreemem()
释放它。
如果没有足够的内存,则可能返回 NULL。
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 及更高版本生成的报告中存在。
- 严重程度;字段内容是
-
- 错误的 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
字段相同,但是当光标位置引用内部生成的命令而不是 Client 端提交的命令时使用。出现此字段时,总是会出现PG_DIAG_INTERNAL_QUERY
字段。
- 该字段的定义与
PG_DIAG_INTERNAL_QUERY
- 内部生成的失败命令的文本。例如,这可以是由 PL/pgSQL 函数发出的 SQL 查询。
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
- 报告错误的源代码功能的名称。
Note
仅为有限数量的错误类型提供模式名称,表名称,列名称,数据类型名称和约束名称的字段。参见Appendix A。不要以为任何这些字段的存在都可以保证另一个字段的存在。核心错误源遵循上面提到的相互关系,但是用户定义的函数可能以其他方式使用这些字段。同样,不要假定这些字段表示当前数据库中的当代对象。
Client 负责格式化显示的信息以满足其需求;特别是它应根据需要断开长行。错误消息字段中出现的换行符应视为段落分隔符,而不是换行符。
libpq 内部生成的错误将具有严重性和主要消息,但通常没有其他字段。 3.0 协议之前的服务器返回的错误将包括严重性和主要消息,有时还包括详细消息,但没有其他字段。
请注意,错误字段仅适用于PGresult
个对象,而不适用于PGconn
个对象;没有PQerrorField
功能。
void PQclear(PGresult *res);
您可以根据需要保持PGresult
对象的存在时间。发出新命令或关闭连接也不会消失。要摆脱它,您必须调用PQclear
。否则,将导致应用程序中的内存泄漏。
33 .3.2. 检索查询结果信息
这些函数用于从表示成功查询结果的PGresult
对象(即状态为PGRES_TUPLES_OK
或PGRES_SINGLE_TUPLE
)中提取信息。它们也可以用于从成功的 Describe 操作中提取信息:Describe 的结果具有与实际执行查询所提供的所有列信息相同的信息,但其行数为零。对于具有其他状态值的对象,这些函数的作用就好像结果具有零行零列。
int PQntuples(const PGresult *res);
int PQnfields(const PGresult *res);
char *PQfname(const PGresult *res,
int column_number);
如果列号超出范围,则返回NULL
。
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
Oid PQftable(const PGresult *res,
int column_number);
如果列号超出范围,或者指定的列不是对表列的简单引用,或者使用 3.0 之前的协议,则返回InvalidOid
。您可以查询系统表pg_class
以确定确切引用了哪个表。
当您包含 libpq 头文件时,将定义类型Oid
和常量InvalidOid
。它们都将是某种整数类型。
int PQftablecol(const PGresult *res,
int column_number);
如果列号超出范围,或者指定的列不是对表列的简单引用,或者使用 3.0 之前的协议,则返回零。
int PQfformat(const PGresult *res,
int column_number);
格式代码零表示文本数据表示,而格式代码 1 表示二进制表示。 (其他代码保留以供将来定义.)
Oid PQftype(const PGresult *res,
int column_number);
您可以查询系统表pg_type
,以获得各种数据类型的名称和属性。内置数据类型的 OID 在源树的文件src/include/catalog/pg_type.h
中定义。
int PQfmod(const PGresult *res,
int column_number);
修饰符值的解释是特定于类型的。它们通常表示精度或尺寸限制。值-1 表示“无可用信息”。大多数数据类型不使用修饰符,在这种情况下,值始终为-1.
int PQfsize(const PGresult *res,
int column_number);
PQfsize
返回在数据库行中为此列分配的空间,换句话说,服务器内部数据类型表示的大小。 (因此,它对 Client 端并不是很有用.)负值表示数据类型为可变长度。
int PQbinaryTuples(const PGresult *res);
不建议使用此功能(与COPY
结合使用时除外),因为单个PGresult
可能在某些列中包含文本数据,而在另一些列中包含二进制数据。 PQfformat
是首选。 PQbinaryTuples
仅在结果的所有列均为二进制(格式 1)时返回 1.
char *PQgetvalue(const PGresult *res,
int row_number,
int column_number);
对于文本格式的数据,由PQgetvalue
返回的值是该字段值的以空值终止的字符串表示形式。对于二进制格式的数据,该值采用由数据类型的typsend
和typreceive
函数确定的二进制表示形式。 (在这种情况下,该值实际上也跟有一个零字节,但这通常不起作用,因为该值可能包含嵌入的 null.)
如果字段值为空,则返回一个空字符串。请参见PQgetisnull
,以区分空值和空字符串值。
PQgetvalue
返回的指针指向PGresult
结构的一部分的存储。一个人不应该修改它指向的数据,如果要在PGresult
结构本身的生存期之后使用它,则必须将其显式复制到其他存储中。
int PQgetisnull(const PGresult *res,
int row_number,
int column_number);
如果该字段为 null,则此函数返回 1;如果该字段包含非 null 值,则返回 0. (请注意,PQgetvalue
将为空字段返回空字符串,而不是空指针.)
int PQgetlength(const PGresult *res,
int row_number,
int column_number);
这是特定数据值的实际数据长度,即PQgetvalue
指向的对象的大小。对于文本数据格式,它与strlen()
相同。对于二进制格式,这是必不可少的信息。请注意,一个人不应该* PQfsize
来获得实际的数据长度。
int PQnparams(const PGresult *res);
此功能仅在检查PQdescribePrepared
的结果时有用。对于其他类型的查询,它将返回零。
Oid PQparamtype(const PGresult *res, int param_number);
此功能仅在检查PQdescribePrepared
的结果时有用。对于其他类型的查询,它将返回零。
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 以前曾使用此函数来打印查询结果,但现在不再如此。请注意,它假定所有数据均为文本格式。
33 .3.3. 检索其他结果信息
这些功能用于从PGresult
对象中提取其他信息。
char *PQcmdStatus(PGresult *res);
通常,这只是命令的名称,但是它可能包含其他数据,例如处理的行数。调用方不应直接释放结果。当关联的PGresult
句柄传递到PQclear
时,它将被释放。
char *PQcmdTuples(PGresult *res);
此函数返回一个字符串,其中包含受生成PGresult
的 SQL 语句影响的行数。仅在执行SELECT
,CREATE TABLE AS
,INSERT
,UPDATE
,DELETE
,MOVE
,FETCH
或COPY
语句或包含INSERT
,UPDATE
或DELETE
语句的已准备查询的EXECUTE
之后,才能使用此函数。如果生成PGresult
的命令是其他命令,则PQcmdTuples
返回空字符串。调用者不应直接释放返回值。当关联的PGresult
句柄传递给PQclear
时,它将被释放。
Oid PQoidValue(const PGresult *res);
char *PQoidStatus(const PGresult *res);
33 .3.4. 转义包含在 SQL 命令中的字符串
char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
PQescapeLiteral
转义用于 SQL 命令的字符串。在 SQL 命令中将数据值作为 Literals 常量插入时,这很有用。某些字符(例如引号和反斜杠)必须转义以防止它们由 SQL 解析器特别解释。 PQescapeLiteral
执行此操作。
PQescapeLiteral
在分配给malloc()
的内存中返回* str
参数的转义版本。当不再需要结果时,应使用PQfreemem()
释放此内存。不需要终止的零字节,也不应该在 length
中计数。 (如果在处理 length
*字节之前找到了终止的零字节,则PQescapeLiteral
会在零处停止;因此,行为就像strncpy
一样.)返回字符串将替换所有特殊字符,以便 PostgreSQL 字符串可以对其进行正确处理。Literals 解析器。还添加了一个终止的零字节。结果字符串中包含必须包含 PostgreSQL 字符串 Literals 的单引号。
错误时,PQescapeLiteral
返回NULL
,并且适当的消息存储在* conn
*对象中。
Tip
在处理从不可靠来源收到的字符串时,进行正确的转义尤为重要。否则存在安全风险:您容易受到“ SQL 注入”攻击的攻击,在这种攻击中,不需要的 SQL 命令会被馈送到数据库中。
请注意,当在PQexecParams
或其同级例程中将数据值作为单独的参数传递时,进行转义既没有必要,也不正确。
char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);
PQescapeIdentifier
转义一个字符串以用作 SQL 标识符,例如表,列或函数名。当用户提供的标识符可能包含特殊字符(否则 SQL 解析器不会将其解释为标识符的一部分),或者当标识符可能包含应保留大小写的大写字符时,此功能很有用。
PQescapeIdentifier
返回通过malloc()
分配的内存中作为 SQL 标识符转义的* str
参数的版本。当不再需要结果时,必须使用PQfreemem()
释放此内存。不需要终止的零字节,也不应该在 length
中计数。 (如果在处理 length
*字节之前找到终止的零字节,则PQescapeIdentifier
会在零处停止;因此,行为就像strncpy
一样.)返回字符串已替换了所有特殊字符,以便可以将其正确处理为 SQL 标识符。还添加了一个终止的零字节。返回字符串也将用双引号引起来。
错误时,PQescapeIdentifier
返回NULL
,并且适当的消息存储在* conn
*对象中。
Tip
与字符串 Literals 一样,为防止 SQL 注入攻击,当从不可靠的来源收到 SQL 标识符时,必须对其进行转义。
size_t PQescapeStringConn(PGconn *conn,
char *to, const char *from, size_t length,
int *error);
PQescapeStringConn
转义字符串 Literals,非常类似于PQescapeLiteral
。与PQescapeLiteral
不同,调用方负责提供适当大小的缓冲区。此外,PQescapeStringConn
不会生成必须括在 PostgreSQL 字符串 Literals 中的单引号。应该在插入结果的 SQL 命令中提供它们。参数* from
指向要转义的字符串的第一个字符,而参数 length
给出此字符串中的字节数。不需要终止的零字节,也不应该在 length
中计数。 (如果在处理 length
字节之前找到终止的零字节,则PQescapeStringConn
停止在零处;因此,行为类似于strncpy
.) to
指向一个缓冲区,该缓冲区至少可以容纳一个比字节多的字节。值 length
的两倍。否则行为未定义。如果 to
和 from
*字符串重叠,则行为同样不确定。
如果* error
参数不是NULL
,则成功时将*error
设置为零,错误时则设置为非零。目前,唯一可能的错误条件是源字符串中的无效多字节编码。错误仍会生成输出字符串,但是可以预期服务器会拒绝该字符串,格式错误。错误时,无论 error
是否为NULL
,都会在 conn
*对象中存储适当的消息。
PQescapeStringConn
返回写入* to
*的字节数,不包括终止的零字节。
size_t PQescapeString (char *to, const char *from, size_t length);
与PQescapeStringConn
的唯一区别是PQescapeString
不使用PGconn
或* error
参数。因此,它无法根据连接属性(例如字符编码)调整其行为,因此它可能会给出错误的结果*。同样,它也无法报告错误情况。
PQescapeString
可以安全地用于一次只能使用一个 PostgreSQL 连接的 Client 端程序中(在这种情况下,它可以找出“幕后”需要知道的内容)。在其他情况下,这是安全隐患,应避免使用PQescapeStringConn
。
unsigned char *PQescapeByteaConn(PGconn *conn,
const unsigned char *from,
size_t from_length,
size_t *to_length);
当某些字节值用作 SQL 语句中bytea
Literals 的一部分时,必须转义。 PQescapeByteaConn
使用十六进制编码或反斜杠转义符转义字节。有关更多信息,请参见Section 8.4。
from
参数指向要转义的字符串的第一个字节,from_length
参数给出此二进制字符串中的字节数。 (终止零字节既不是必需的,也不是计数的.)to_length
*参数指向一个变量,该变量将保存所得的转义字符串长度。该结果字符串长度包括结果的终止零字节。
PQescapeByteaConn
在分配给malloc()
的内存中返回* from
*参数二进制字符串的转义版本。当不再需要结果时,应使用PQfreemem()
释放此内存。返回字符串将替换所有特殊字符,以便 PostgreSQL 字符串 Literals 解析器和bytea
Importing 函数可以正确处理它们。还添加了一个终止的零字节。必须用 PostgreSQL 字符串 Literals 括起来的单引号不是结果字符串的一部分。
发生错误时,将返回空指针,并将适当的错误消息存储在* conn
*对象中。当前,唯一可能的错误是结果字符串的内存不足。
unsigned char *PQescapeBytea(const unsigned char *from,
size_t from_length,
size_t *to_length);
与PQescapeByteaConn
的唯一区别是PQescapeBytea
不采用PGconn
参数。因此,PQescapeBytea
只能在一次使用单个 PostgreSQL 连接的 Client 端程序中安全使用(在这种情况下,它可以“了解其幕后情况”)。如果在使用多个数据库连接的程序中使用(在这种情况下,请使用PQescapeByteaConn
),它“可能会给出错误的结果”。
unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
from
参数指向一个字符串,例如应用于bytea
列时PQgetvalue
可能返回。PQunescapeBytea
将此字符串表示形式转换为其二进制表示形式。它返回指向分配给malloc()
或错误时NULL
的缓冲区的指针,并将缓冲区的大小放入to_length
*中。当不再需要结果时,必须使用PQfreemem
释放结果。
此转换与PQescapeBytea
并不完全相反,因为从PQgetvalue
接收到该字符串时,预计该字符串不会“转义”。特别是,这意味着不需要考虑字符串引用,因此不需要PGconn
参数。