Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

32.3.  命令执行函数 #

32.3.1. 主要函数
32.3.2. 检索查询结果信息
32.3.3. 检索其他结果信息
32.3.4. 转义用于包含在 SQL 命令中的字符串

一旦成功建立与数据库服务器的连接,就会使用此处描述的函数执行 SQL 查询和命令。

32.3.1.  主要函数 #

PQexec #

向服务器提交命令并等待结果。

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

返回 PGresult 指针或空指针。通常返回非空指针,除非内存不足或发生严重错误,例如无法向服务器发送命令。应当调用 PQresultStatus 函数来检查任何错误的返回值(包括空指针值,在这种情况下,它将返回 PGRES_FATAL_ERROR)。使用 PQerrorMessage 来获取有关此类错误的更多信息。

命令字符串可以包含多个 SQL 命令(用分号分隔)。在单个 PQexec 调用中发送的多个查询在单个事务中处理,除非查询字符串中包含明确的 BEGIN/COMMIT 命令,将其划分为多个事务。(有关服务器如何处理多查询字符串的更多详细信息,请参见 第 53.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[]。(当 nParams 为零时,数组指针可以是 NULL。)

paramTypes[]

按 OID 指定要分配给参数符号的数据类型。如果 paramTypesNULL,或数组中的任何特定元素为零,则服务器会像处理未类型化的文本文本串一样为参数符号推断一个数据类型。

paramValues[]

指定参数的实际值。此数组中的一个空指针表示对应的参数为空;否则,指针指向一个以零结尾的文本串(对于文本格式)或服务器所期望格式的二进制数据(对于二进制格式)。

paramLengths[]

指定二进制格式参数的实际数据长度。对于空参数和文本格式参数,该值将被忽略。如果不存在二进制参数,则数组指针可以为空。

paramFormats[]

指定参数是文本(在对应参数的数组条目中放入零)还是二进制(在对应参数的数组条目中放入一)。如果数组指针为空,则假定所有参数都是文本串。

以二进制格式传递的值需要了解后端所期望的内部表示。例如,整数必须按网络字节顺序传递。传递 numeric 值需要了解在 src/backend/utils/adt/numeric.c::numeric_send()src/backend/utils/adt/numeric.c::numeric_recv() 中实施的服务器存储格式。

resultFormat

指定零以文本格式获取结果,或指定一以二进制格式获取结果。(目前没有针对以不同格式获取不同结果列的规定,尽管底层协议中可以实现该目的。)

相对于 PQexecPQexecParams 的主要优势在于参数值可以与命令串分开,这样可以避免进行繁琐且容易出错的引用和转义操作。

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

该函数从 query 字符串(必须包含一个 SQL 命令)创建名为 stmtName 的预编译语句。stmtName 可以是 "" 以创建一个未命名语句,在这种情况下,任何预先存在的未命名语句都会被自动替换;否则,如果语句名称已在当前会话中定义,那么就会出错。如果使用了任何参数,那么它们在查询中被引用为 $1$2 等。nParams 是预先在数组 paramTypes[] 中指定了类型的参数的数量。(索引指针在 nParams 等于零时可以为 NULL。)paramTypes[] 通过 OID 指定要分配给参数符号的数据类型。如果 paramTypesNULL,或者数组中的任何特定元素为零,那么服务器会以与未键入文本字符串相同的方式为参数符号分配数据类型。此外,该查询可以使用参数符号且高于 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,但要执行的命令通过指定一个预先准备的语句来指定,而不是给出一个查询字符串。该功能允许将要重复使用的命令进行解析和规划一次,而不是在每次执行它们时都进行。必须在当前会话中预先准备该语句。

这些参数与 PQexecParams 相同,只不过指定的是预编译语句的名称而不是查询字符串,且不存在 paramTypes[] 参数(它不是必需的,因为已在创建预编译语句时确定了其参数类型)。

PQdescribePrepared #

提交一个请求来获取指定的准备语句的信息,并等待完成。

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

PQdescribePrepared 允许应用程序获取之前准备好的语句的信息。

stmtName 可以为 ""NULL 来引用未命名的语句,否则它必须为现有的准备语句的名称。如果成功,将返回一个状态为 PGRES_COMMAND_OKPGresult。可以对 PQnparamsPQparamtype 函数应用此 PGresult 来获取有关准备语句的参数信息,还可以对函数 PQnfields, PQfname, PQftype 等应用此 PGresult 来获取有关语句的结果列(如果有)的信息。

PQdescribePortal #

提交一个请求来获取指定门户的信息,并等待完成。

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

PQdescribePortal 允许应用程序获取先前创建的门户的信息。(libpq 不会提供直接访问任何门户的方法,但您可以使用此函数来查看使用 DECLARE CURSOR SQL 命令创建的游标的属性。)

portalName 可以为 ""NULL 来引用未命名的门户,否则它必须为现有门户的名称。如果成功,将返回一个状态为 PGRES_COMMAND_OKPGresult。可以对 PQnfields, PQfname, PQftype 等函数应用 PGresult 来获取有关门户的结果列(如果有)的信息。

PQclosePrepared #

提交一个请求来关闭指定的准备语句,并等待完成。

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

PQclosePrepared 允许应用程序关闭先前准备好的语句。关闭语句将释放服务器上所有与之关联的资源并允许其名称被重用。

stmtName 可以是 ""NULL 以引用未命名的语句。如果没有以此名称存在的语句,这种情况也可接受,此时操作无效。成功后,返回包含 PGRES_COMMAND_OK 状态的 PGresult

PQclosePortal #

提交一个请求以关闭已指定的入口,并等待完成。

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 #

不返回数据的命令成功执行。

PGRES_TUPLES_OK #

返回数据的命令成功执行(例如 SELECTSHOW)。

PGRES_COPY_OUT #

数据传输(从服务器)开始复制输出。

PGRES_COPY_IN #

已启动数据传输(到服务器)。

PGRES_BAD_RESPONSE #

无法理解服务器的响应。

PGRES_NONFATAL_ERROR #

出现了一个非致命错误(一个通知或警告)。

PGRES_FATAL_ERROR #

出现了一个致命错误。

PGRES_COPY_BOTH #

已启动 Copy In/Out(到服务器和从服务器)数据传输。此功能目前仅用于流复制,因此此状态不应在普通应用程序中出现。

PGRES_SINGLE_TUPLE #

PGresult 包含当前命令的一个结果元组。此状态仅在为查询选择了单行模式时出现(参见第 32.6 节)。

PGRES_TUPLES_CHUNK #

PGresult 包含当前命令的多个结果元组。此状态仅在为查询选择了分块模式时出现(参见第 32.6 节)。元组数不会超过传递给 PQsetChunkedRowsMode 的限制。

PGRES_PIPELINE_SYNC #

PGresult 表示管道模式中的一个同步点,由 PQpipelineSyncPQsendPipelineSync 请求。此状态仅在选择了管道模式时出现。

PGRES_PIPELINE_ABORTED #

PGresult 表示已从服务器收到错误的管道。必须反复调用 PQgetResult,每次它都会返回此状态代码,直到当前管道结束时,此时它将返回 PGRES_PIPELINE_SYNC,可恢复正常处理。

如果结果状态是 PGRES_TUPLES_OKPGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNK,那么可以将下列描述的函数用于检索查询中返回的行。请注意,恰好检索到零行的 SELECT 命令仍显示 PGRES_TUPLES_OKPGRES_COMMAND_OK 适用于绝不会返回行的命令(例如没有 RETURNING 子句的 INSERTUPDATE 等)。PGRES_EMPTY_QUERY 响应可能表明客户端软件存在错误。

状态为 PGRES_NONFATAL_ERROR 的结果将绝不会由 PQexec 或其他查询执行函数直接返回;此类结果将传递至通知处理器(请参见 第 32.13 节)。

PQresStatus #

PQresultStatus 返回的枚举类型转换为描述状态代码的字符串常量。调用者不应释放结果。

char *PQresStatus(ExecStatusType status);
PQresultErrorMessage #

返回与命令关联的错误消息,如果无错误,则返回空字符串。

char *PQresultErrorMessage(const PGresult *res);

如果存在错误,则返回的字符串将包含尾随换行符。调用者不应直接释放结果。在将关联的 PGresult 句柄传递至 PQclear 时,将会释放结果。

紧随 PQexecPQgetResult 调用之后,PQerrorMessage(在连接处)将返回与 PQresultErrorMessage(在结果中)相同的字符串。但是,PGresult 将保留其错误消息,直至被销毁为止,而连接的错误消息会在 subsequent 操作执行时更改。它会保留其错误消息,直至被销毁为止,而连接的错误消息会在 subsequent 操作执行时更改。当您需要知道与特定 PGresult 关联的状态时,请使用 PQresultErrorMessage;当您需要知道最新连接操作的状态时,请使用 PQerrorMessage

PQresultVerboseErrorMessage #

返回 PGresult 对象关联的错误消息的重新格式化版本。

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

某些情况下,客户端可能希望获取之前报告错误的更详细版本。 PQresultVerboseErrorMessage 通过计算当 generate 给定的 PGresult 时连接的指定详细信息设置生效,PQresultErrorMessage 会生成的消息来解决此问题。如果 PGresult 不是错误结果,则会报告 PGresult 不是错误结果。返回的字符串包含一个尾换行符。

与从 PGresult 提取数据的其他大多数函数不同,此函数的结果是一个新分配的字符串。当不再需要该字符串时,调用者必须使用 PQfreemem() 释放它。

如果内存不足,则可能返回 NULL。

PQresultErrorField #

返回错误报告的各个字段。

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

fieldcode 是错误字段标识符;请参见下面列出的符号。如果 PGresult 不是错误或警告结果或不包含指定字段,则返回 NULL。字段值通常不包括尾换行符。调用者不应直接释放结果。当关联的 PGresult 句柄传递给 PQclear 时,它将被释放。

可用以下字段代码

PG_DIAG_SEVERITY #

严重性;字段内容为 ERRORFATAL、或 PANIC(在错误消息中),或 WARNINGNOTICEDEBUGINFO、或 LOG(在通知消息中),或其中一个的本地化翻译。始终提供。

PG_DIAG_SEVERITY_NONLOCALIZED #

错误级别;字段内容为 ERRORFATALPANIC (在错误消息中),或 WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。这与 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 #

内部生成的一个失败命令的文本。例如,它可能是由 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 #

报告错误的源代码函数的名称。

注意

仅在有限的错误类型中提供架构名称、表名称、列名称、数据类型名称和约束名称的字段;请参阅 附录 A。请勿假设其中任何字段的存在保证了其他字段的存在。核心错误源遵守上面提到的相互关系,但用户定义的函数可能以其他方式使用这些字段。同样,请勿假设这些字段表示当前数据库中的当代对象。

客户端负责根据其需要格式化显示信息;尤其是,它应该按需要换行。出现在错误消息字段中的换行符应被视为段落分隔符,而非换行符。

libpq 内部生成的错误将具有严重性和主要消息,但通常没有其他字段。

请注意,错误字段仅可用自 PGresult 对象,不能用自 PGconn 对象;没有 PQerrorField 函数。

PQclear #

释放与 PGresult 关联的存储。不再需要时应该通过 PQclear 释放每个命令结果。

void PQclear(PGresult *res);

如果参数是 NULL 指针,则不执行操作。

您可以保留 PGresult 对象只要您需要它;当您发布新命令或关闭连接时它并不会消失。要摆脱它,您必须调用 PQclear。未执行此操作将导致您的应用程序内存泄露。

32.3.2. 检索查询结果信息 #

这些函数用于从一个表示成功查询结果(即具有状态 PGRES_TUPLES_OKPGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNK)的 PGresult 对象中提取信息。它们还可以用于从一个成功的描述操作中提取信息:一个描述结果具有实际执行查询将提供的全部同种列信息,但它没有行。对于具有其他状态值的那些对象,这些函数将表现得好像该结果有 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 #

返回构成指定查询结果列的列的列号(在其表中)。查询结果列号从 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内置数据类型的 s 在 catalog/pg_type_d.h 文件中定义,该文件在 PostgreSQL 安装的 include 目录中。

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 返回的值是字段值的以 null 结尾的字符串表示形式。对于二进制格式的数据,该值以数据类型的 typsendtypreceive 函数确定的二进制表示形式存储。(在这种情况下,该值实际上后面还跟着一个零字节,但这通常没有用,因为该值可能包含嵌入的 null 值。)

如果字段值为空,则返回空字符串。请参阅 PQgetisnull 以区分空值和空字符串值。

PQgetvalue 返回的指针指向属于 PGresult 结构的一部分存储。你不应修改它指向的数据, 并且如果要在 PGresult 结构自身的生命周期之外使用它, 你必须显式地将数据复制到其他存储中。

PQgetisnull #

测试字段的空值。行号和列号从 0 开始。

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

如果字段为空则此函数返回 1, 如果它包含非空值则返回 0。(注意, PQgetvalue 会返回空字符串而不是空指针, 表示字段为空)。

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 #

返回指示的语句参数的数据类型。参数号从 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用于打印查询结果,但现在不再这样了。请注意,它假设所有数据均为文本格式。

32.3.3. 检索其他结果信息 #

这些函数用于从PGresult对象中提取其他信息。

PQcmdStatus #

返回生成PGresult的 SQL 命令的命令状态标记。

char *PQcmdStatus(PGresult *res);

通常这只命令的名称,但它可能包括其他数据,例如处理的行数。调用方不应直接释放结果。当关联的PGresult句柄传递到PQclear时,它将被释放。

PQcmdTuples #

返回受 SQL 命令影响的行数。

char *PQcmdTuples(PGresult *res);

此函数返回一个字符串,其中包含受SQL生成PGresult的语句影响的行数。此函数仅可用于执行SELECTCREATE TABLE ASINSERTUPDATEDELETEMERGEMOVEFETCHCOPY语句,或包含INSERTUPDATEDELETEMERGE语句的已准备查询的EXECUTE后。如果其他任何内容生成了PGresult,则PQcmdTuples将返回一个空字符串。调用方不应直接释放返回值。当关联的PGresult句柄传递到PQclear时,它将被释放。

PQoidValue #

如果SQL命令是以INSERT形式插入一行到具有 OID的表中,或者是以EXECUTE形式执行包含适当INSERT语句的已准备查询,则返回已插入行的 OID。否则,此函数返回 InvalidOid。如果受INSERT语句影响的表不包含 OID,此函数还将返回 InvalidOid

Oid PQoidValue(const PGresult *res);
PQoidStatus #

此函数现已弃用,建议使用 PQoidValue,因为它不是线程安全的。它返回一个包含插入行 OID 的字符串,而 PQoidValue 返回 OID 值。

char *PQoidStatus(const PGresult *res);

32.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。)返回字符串中所有特殊字符均已被替换,以便能够由 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 #

PQescapeStringPQescapeStringConn 的一个更老、废弃的版本。

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

PQescapeStringConn 唯一的区别在于,PQescapeString 不会获取 PGconn 或 `error` 参数。正因如此,它无法根据连接属性(如字符编码)调整其行为,因此 它可能会给出错误的结果。此外,它也没有办法报告错误条件。

PQescapeString 可安全地用于一次只使用一个 PostgreSQL 连接的客户端程序中(在这种情况下,它可以找到需要了解的内容,幕后)。在其他情况下,会出现安全风险,应该避免使用 PQescapeStringConn

PQescapeByteaConn #

使用 bytea 类型转义二进制数据,以供 SQL 命令使用。与 PQescapeStringConn 一样,这仅在将数据直接插入到 SQL 命令字符串时使用。

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

在语句中使用时,某些字节值在用作 bytea 文字的一部分时需要转义。SQLPQescapeByteaConn 使用十六进制编码或反斜杠转义对字节进行转义。有关更多信息,请参见 第 8.4 节

from 参数指向要转义的字符串的第一个字节,from_length 参数给出了这个二进制字符串中的字节数。(终止零字节不是必需的,也不会计算在内)。to_length 参数指向一个变量,其中保存结果转义字符串长度。这个结果字符串长度包括结果的终止零字节。

PQescapeByteaConn 以使用 malloc() 分配的内存为 from 参数二进制字符串的转义版本返回一个版本。当不再需要结果时,应使用 PQfreemem() 释放这个内存。返回字符串的所有特殊字符都被替换,以便 PostgreSQL 字符串文字解析器和 bytea 输入函数能够正确处理它们。还添加了一个终止零字节。必须将 PostgreSQL 字符串文字包围起来的单引号不是结果字符串的一部分。

如果出错,返回空指针,并一个适当的错误消息存储在 conn 对象中。目前,唯一的可能错误就是结果字符串的内存不足。

PQescapeBytea #

PQescapeByteaPQescapeByteaConn 的一个较旧已被弃用的版本。

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 参数。