支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

32.3. 命令执行函数 #

一旦与数据库服务器的连接成功建立,这里描述的函数将用于执行 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

指定零以文本格式获取结果,或指定一以二进制格式获取结果。(目前没有提供以不同格式获取不同结果列的规定,尽管这在底层协议中是可能的。)

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

该函数从 query 字符串创建一个名为 stmtName 的预备语句,该字符串必须包含单个 SQL 命令。stmtName 可以是 "" 以创建一个未命名的语句,在这种情况下,任何预先存在的未命名语句都会被自动替换;否则,如果该语句名称已经在当前会话中定义,则会出错。如果使用任何参数,它们在查询中被引用为 $1$2 等。nParams 是在数组 paramTypes[] 中预先指定类型的参数数量。(当 nParams 为零时,数组指针可以是 NULL。)paramTypes[] 通过 OID 指定要分配给参数符号的数据类型。如果 paramTypesNULL,或者数组中的任何特定元素为零,则服务器会以与处理未类型化文字字符串相同的方式为参数符号分配数据类型。此外,查询可以使用编号高于 nParams 的参数符号;也会为这些符号推断数据类型。(请参阅 PQdescribePrepared 以了解如何找出推断的数据类型。)

PQexec 一样,结果通常是一个 PGresult 对象,其内容指示服务器端的成功或失败。空结果表示内存不足或无法发送命令。使用 PQerrorMessage 获取有关此类错误的更多信息。

也可以通过执行 SQL PREPARE 语句来创建用于 PQexecPrepared 的预备语句。

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,以获取有关预备语句参数的信息,并且函数 PQnfieldsPQfnamePQftype 等提供有关语句的结果列(如果有)的信息。

PQdescribePortal #

提交请求以获取有关指定游标的信息,并等待完成。

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

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

portalName 可以是 ""NULL 以引用未命名的游标,否则它必须是现有游标的名称。成功时,将返回一个状态为 PGRES_COMMAND_OKPGresult。函数 PQnfieldsPQfnamePQftype 等可以应用于 PGresult,以获取有关游标的结果列(如果有)的信息。

PQclosePrepared #

提交请求以关闭指定的预备语句,并等待完成。

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

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

stmtName 可以是 ""NULL 以引用未命名的语句。如果不存在具有此名称的语句,则操作是空操作。成功时,将返回一个状态为 PGRES_COMMAND_OKPGresult

PQclosePortal #

提交请求以关闭指定的游标,并等待完成。

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

PQclosePortal 允许应用程序触发先前创建的游标的关闭。关闭游标会释放其在服务器上的所有关联资源,并允许重用其名称。(libpq 不提供对游标的任何直接访问,但是您可以使用此函数来关闭使用 DECLARE CURSOR SQL 命令创建的游标。)

portalName 可以是 ""NULL 以引用未命名的游标。如果不存在具有此名称的游标,则操作是空操作。成功时,将返回一个状态为 PGRES_COMMAND_OKPGresult

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 #

Copy Out(从服务器)数据传输开始。

PGRES_COPY_IN #

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 用于永远不会返回行的命令(INSERT 或没有 RETURNING 子句的 UPDATE 等)。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 将保留其错误消息直到销毁,而连接的错误消息将在后续操作完成时更改。当您想知道与特定 PGresult 关联的状态时,请使用 PQresultErrorMessage;当您想知道连接上最新操作的状态时,请使用 PQerrorMessage

PQresultVerboseErrorMessage #

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

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

在某些情况下,客户端可能希望获得先前报告的错误的更详细版本。PQresultVerboseErrorMessage 通过计算如果指定的详细级别设置在生成给定 PGresult 时对连接有效,则 PQresultErrorMessage 将生成的错误消息来解决此需求。如果 PGresult 不是错误结果,则会报告PGresult 不是错误结果。返回的字符串包含尾随换行符。

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

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

PQresultErrorField #

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

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

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

以下字段代码可用

PG_DIAG_SEVERITY #

严重性;字段内容为 ERRORFATALPANIC(在错误消息中),或 WARNINGNOTICEDEBUGINFOLOG(在通知消息中),或其中一个的本地化翻译。始终存在。

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. 检索查询结果信息 #

这些函数用于从表示成功查询结果的 PGresult 对象中提取信息(即,具有状态 PGRES_TUPLES_OKPGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNK 的对象)。它们还可以用于从成功的 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 以准确确定引用的表。

当您包含 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内置数据类型的 OID 定义在 PostgreSQL 安装的 include 目录中的 catalog/pg_type_d.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 是首选。PQbinaryTuples 仅当结果的所有列都是二进制(格式 1)时才返回 1。

PQgetvalue #

返回 PGresult 的一行的单个字段值。行号和列号从 0 开始。调用者不应直接释放结果。当关联的 PGresult 句柄传递给 PQclear 时,它将被释放。

char *PQgetvalue(const PGresult *res,
                 int row_number,
                 int column_number);

对于文本格式的数据,PQgetvalue 返回的值是字段值的以 null 结尾的字符串表示形式。对于二进制格式的数据,该值采用由数据类型的 typsendtypreceive 函数确定的二进制表示形式。(在这种情况下,该值实际上也后跟一个零字节,但这通常没什么用,因为该值很可能包含嵌入的 null。)

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

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,      /* 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 #

如果命令是 INSERT,并且该命令恰好将一行插入到具有 OID 的表中,或者如果命令是包含适合的 INSERT 语句的预备查询的 EXECUTE,则返回插入行的 OIDSQL否则,此函数将返回 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 返回使用 malloc() 分配的内存中 str 参数的转义版本。当不再需要结果时,应使用 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 返回使用 malloc() 分配的内存中转义为 SQL 标识符的 str 参数的版本。当不再需要结果时,必须使用 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 的值大两倍的字节数,否则行为未定义。如果 tofrom 字符串重叠,则行为同样未定义。

如果 error 参数不是 NULL,则成功时 *error 设置为零,失败时设置为非零。目前,唯一可能的错误情况涉及源字符串中的无效多字节编码。错误时仍会生成输出字符串,但可以预期服务器会将其拒绝为格式错误。发生错误时,会在 conn 对象中存储一条合适的消息,无论 error 是否为 NULL

PQescapeStringConn 返回写入 to 的字节数,不包括终止零字节。

PQescapeString #

PQescapeStringPQescapeStringConn 的较旧的、已弃用的版本。

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

PQescapeStringConn 的唯一区别在于,PQescapeString 不采用 PGconnerror 参数。因此,它无法根据连接属性(例如字符编码)调整其行为,因此可能会给出错误的结果。此外,它无法报告错误情况。

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);

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

from 参数指向要转义的字符串的第一个字节,from_length 参数给出此二进制字符串中的字节数。(不需要也不计算终止零字节。)to_length 参数指向一个变量,该变量将保存生成的转义字符串的长度。此结果字符串长度包括结果的终止零字节。

PQescapeByteaConn 返回一个经过转义的 from 参数的二进制字符串版本,该字符串在内存中使用 malloc() 分配。当不再需要该结果时,应使用 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 参数。

提交更正

如果您在文档中发现任何不正确、与特定功能不符或需要进一步澄清的内容,请使用此表单报告文档问题。