2025年9月25日: PostgreSQL 18 发布!
支持版本: 当前 (18) / 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 命令将其划分为多个事务。(有关服务器如何处理多查询字符串的更多详细信息,请参阅 第 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,但提供额外的功能:参数值可以与命令字符串本身分开指定,并且可以请求文本或二进制格式的查询结果。

函数参数是

conn

发送命令的连接对象。

command

要执行的 SQL 命令字符串。如果使用参数,则在命令字符串中以 $1$2 等形式引用。

nParams

提供的参数数量;它是数组 paramTypes[]paramValues[]paramLengths[]paramFormats[] 的长度。(当 nParams 为零时,数组指针可以为 NULL。)

paramTypes[]

通过 OID 指定要分配给参数符号的数据类型。如果 paramTypesNULL,或者数组中的任何特定元素为零,则服务器以与处理无类型文字字符串相同的方式推断参数符号的数据类型。

paramValues[]

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

paramLengths[]

指定二进制格式参数的实际数据长度。对于空参数和文本格式参数,它将被忽略。当没有二进制参数时,数组指针可以为 null。

paramFormats[]

指定参数是文本(在相应参数的数组条目中放置零)还是二进制(在相应参数的数组条目中放置一)。如果数组指针为 null,则所有参数都被假定为文本字符串。

以二进制格式传递的值需要了解后端预期的内部表示。例如,整数必须以网络字节序传递。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 获取有关此类错误的更多信息。

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

PQdescribePortal #

提交获取指定游标信息(portal)的请求,并等待完成。

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 适用于从不返回行的命令(没有 RETURNING 子句的 INSERTUPDATE 等)。PGRES_EMPTY_QUERY 的响应可能表示客户端软件中存在错误。

PQexec 或其他查询执行函数绝不会直接返回状态为 PGRES_NONFATAL_ERROR 的结果;此类结果会传递给通知处理器(请参阅 第 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. 检索查询结果信息 #

这些函数用于从表示成功查询结果(即,状态为 PGRES_TUPLES_OKPGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNK)的 PGresult 对象中提取信息。它们还可以用于从成功的 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 以获取各种数据类型的名称和属性。内置数据类型的OIDPostgreSQL 安装的 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 返回的值是字段值的以空字符结尾的字符串表示形式。对于二进制格式的数据,该值是数据类型的 typsendtypreceive 函数确定的二进制表示形式。(在这种情况下,该值实际上也后跟一个零字节,但这通常没有用,因为该值可能包含嵌入的空字符。)

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

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

PQgetisnull #

测试字段是否为 null 值。行号和列号从 0 开始。

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

如果字段为 null,则此函数返回 1;如果它包含非 null 值,则返回 0。(请注意,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 的结果时有用。对于其他类型的结果,它将返回零。

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 #

如果SQL命令是 INSERT 命令,并且仅向具有 OID 的表中插入了一行,或者包含合适的 INSERT 语句的预处理查询的 EXECUTE 命令,则返回插入行的 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 在使用 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 返回 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 值的字节的缓冲区,否则行为未定义。如果 tofrom 字符串重叠,行为也未定义。

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

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

PQescapeString #

PQescapeStringPQescapeStringConn 的旧版,已弃用。

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

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

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 返回在用 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 参数。

提交更正

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