Postgresql 中文操作指南

34.3. Command Execution Functions #

一旦成功建立与数据库服务器的连接,这里描述的功能就可用于执行 SQL 查询和命令。

34.3.1. Main Functions #

  • PQexec #

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

PGresult *PQexec(PGconn *conn, const char *command);
  • 返回 PGresult 指针或一个空指针。一般会返回一个非空指针,除了内存不足或无法向服务器发送命令等严重错误的情况。应对返回值调用 PQresultStatus 函数检查错误(包括空指针值,在这种情况下,它会返回 PGRES_FATAL_ERROR )。使用 PQerrorMessage 获得有关此类错误的更多信息。

命令字符串可以包括多个 SQL 命令(用分号分隔)。在单个 PQexec 调用中发送的多条查询会作为一个单独的事务处理,除非在查询字符串中包括明确的 BEGIN / COMMIT 命令以将其划分为多个事务。(有关服务器处理多查询字符串的更多详细信息,请参阅 Section 55.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);
  • PQexecParamsPQexec 类似,但它提供了附加功能:可以将参数值与命令字符串本身分开指定,并且可以以文本或二进制格式请求查询结果。

  • The function arguments are:

    • 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 注入攻击的额外防御措施,具有一定的实用性。

Tip

通过 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 获得有关此类错误的更多信息。

也可以通过执行 SQL PREPARE 语句来创建准备好的语句以便与 PQexecPrepared 一起使用。此外,尽管没有用于删除准备好的语句的 libpq 函数,但可以使用 SQL DEALLOCATE 语句来达到这一目的。

  • PQexecPrepared #

    • 发送请求以使用给定参数执行预准备语句,并等待结果。

PGresult *PQexecPrepared(PGconn *conn,
                         const char *stmtName,
                         int nParams,
                         const char * const *paramValues,
                         const int *paramLengths,
                         const int *paramFormats,
                         int resultFormat);
  • PQexecPreparedPQexecParams 类似,但是要执行的命令的指定是通过命名一个先前准备好的语句(而不是提供一个查询字符串)进行的。这一特性允许将要重复使用的命令解析并规划一次,而不是在每次执行时重复。该语句必须先前已在当前会话中准备。

  • 这些参数与 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 以获取有关入口的结果列(如果有)的信息。

PGresult 结构封装了服务器返回的结果。libpq 应用程序程序员应注意维护 PGresult 抽象。使用以下访问器函数获取 PGresult 的内容。避免直接引用 PGresult 结构的字段,因为它们将来可能会更改。

  • PQresultStatus #

    • 返回命令的结果状态。

ExecStatusType PQresultStatus(const PGresult *res);
  • PQresultStatus 可以返回以下值之一:

  • 如果结果状态为 PGRES_TUPLES_OKPGRES_SINGLE_TUPLE,则可以使用下面描述的函数来检索查询返回的行。请注意,返回零行的 SELECT 命令仍显示 PGRES_TUPLES_OKPGRES_COMMAND_OK 适用于永远不会返回行的命令(没有 RETURNING 子句的 INSERTUPDATE 等)。PGRES_EMPTY_QUERY 的响应可能表明客户端软件中存在错误。

  • 状态为 PGRES_NONFATAL_ERROR 的结果永远不会被 PQexec 或其他查询执行函数直接返回;此类结果将改为传递给提示处理程序(请参阅 Section 34.13 )。

    • PQresStatus #

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

char *PQresStatus(ExecStatusType status);
  • PQresultErrorMessage #

    • 返回与命令关联的错误消息,如果不存在错误,则返回一个空字符串。

char *PQresultErrorMessage(const PGresult *res);
  • 如果出现错误,返回的字符串将包括一个尾随换行符。调用者不应直接释放结果。当关联的 PGresult 句柄传递给 PQclear 时,将释放它。

  • 紧跟在 PQexecPQgetResult 调用之后, PQerrorMessage (在连接中)将返回与 PQresultErrorMessage (在结果中)相同的字符串。但是, PGresult 将保留其错误消息直到销毁,而连接的错误消息将在执行后续操作时更改。使用 PQresultErrorMessage 了解与特定 PGresult 关联的状态;使用 PQerrorMessage 了解连接中最新操作的状态。

    • PQresultVerboseErrorMessage #

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

char *PQresultVerboseErrorMessage(const PGresult *res,
                                  PGVerbosity verbosity,
                                  PGContextVisibility show_context);
  • 在某些情况下,客户端可能希望获得先前报告的错误的更详细的版本。 PQresultVerboseErrorMessage 通过计算 PQresultErrorMessage 将生成的错误,如果在给定的 PGresult 生成时指定的长篇大论设置为连接的默认设置,来满足此需要。如果 PGresult 不是错误结果,则会报告“PGresult 不是错误结果”。返回的字符串包含一个尾随换行符。

  • 与大多数其他用于从 PGresult 提取数据的函数不同,该函数返回的新分配字符串。在不再需要字符串时,调用方必须使用 PQfreemem() 释放它。

  • 如果没有足够的内存,则可能返回 NULL。

    • PQresultErrorField #

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

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

  • 可用的字段代码如下:

  • 客户端负责格式化显示的信息以满足其需要;特别是它应根据需要拆分长行。错误消息字段中出现的换行符应视为段落符,而不是换行符。

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

  • 请注意,错误字段只可在 PGresult 对象中使用,不可在 PGconn 对象中使用;没有 PQerrorField 函数。

    • PQclear #

  • 释放与 PGresult 关联的存储空间。当不再需要每个命令结果时,应通过 PQclear 释放它。

void PQclear(PGresult *res);
  • 如果参数是 NULL 指针,则不执行任何操作。

  • 您可以保留 PGresult 对象,只要您需要它;当您发出新命令,甚至关闭连接时,它也不会消失。要摆脱它,您必须调用 PQclear 。如果不这样做,将导致应用程序出现内存泄漏。

    • 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 #

  • A fatal error occurred.

    • PGRES_COPY_BOTH #

  • 复制输入/输出(到和从服务器)数据传输已开始。此功能当前仅用于流复制,所以在普通应用程序中不应该出现此状态。

    • PGRES_SINGLE_TUPLE #

  • PGresult 包含当前命令的单个结果元组。此状态仅在为查询选择了单行模式时才会发生(请参阅 Section 34.6)。

    • PGRES_PIPELINE_SYNC #

  • PGresult 代表 PQpipelineSync 请求的管道模式中的同步点。此状态仅在选择管道模式时发生。

    • PGRES_PIPELINE_ABORTED #

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

    • PG_DIAG_SEVERITY #

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

    • PG_DIAG_SEVERITY_NONLOCALIZED #

  • 严重性;字段内容为 ERRORFATALPANIC(在错误消息中),或 WARNINGNOTICEDEBUGINFOLOG(在通知消息中)。这与 PG_DIAG_SEVERITY 字段相同,不同之处在于内容永远不会被本地化。这仅在 PostgreSQL 9.6 及更高版本生成的报告中出现。

    • PG_DIAG_SQLSTATE #

  • 错误的 SQLSTATE 代码。SQLSTATE 代码标识发生的错误类型;它可由前端应用程序用于根据特定的数据库错误执行特定操作(例如错误处理)。有关可能出现的 SQLSTATE 代码列表,请参阅 Appendix A。此字段不可本地化,并且始终存在。

    • PG_DIAG_MESSAGE_PRIMARY #

  • 主要的人类可读错误消息(通常是一行)。始终存在。

    • PG_DIAG_MESSAGE_DETAIL #

  • 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 #

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

Note

只有在有限数量的错误类型中提供了架构名称、表名称、列名称、数据类型名称和约束名称的字段;请参阅 Appendix A。不要以为存在其中任何字段就能保证其他字段也存在。核心错误源会观察到上述相互关系,但用户定义的函数可能会以其他方式使用这些字段。出于同样的原因,不要以为这些字段表示当前数据库中的当代对象。

34.3.2. Retrieving Query Result Information #

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

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

  • PQgetvalue 返回的指针指向属于 PGresult 结构的一部分的存储。不应该修改它所指向的数据,并且在需要在超出 PGresult 结构本身的生命期后使用数据时,必须将数据显式复制到其他存储中。

    • PQgetisnull #

  • 测试一个字段是否为空值。行号和列号从 0 开始。

int PQgetisnull(const PGresult *res,
                int row_number,
                int column_number);
  • 此函数在字段为 null 时返回 1,而在它包含非 null 值时返回 0。(注意, PQgetvalue 将为 null 字段返回一个空字符串,而不是一个 null 指针。)

    • PQgetlength #

  • 以字节为单位返回字段值的实际长度。行号和列号从 0 开始。

int PQgetlength(const PGresult *res,
                int row_number,
                int column_number);
  • 这是特定数据值的实际数据长度,即 PQgetvalue 指向的对象的大小。对于文本数据格式,此与 strlen() 相同。对于二进制格式,此为基本信息。注意,人们应该 not 依赖 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 用于打印查询结果,但现在不再使用。注意,它假定所有数据都采用文本格式。

34.3.3. Retrieving Other Result Information #

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

  • PQcmdStatus #

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

char *PQcmdStatus(PGresult *res);
  • 这通常只是命令的名称,但它可能包含其他数据(例如已处理的行数)。调用者不应直接释放结果。它将在关联 PGresult 句柄传递到 PQclear 时被释放。

    • PQcmdTuples #

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

char *PQcmdTuples(PGresult *res);
  • 此函数返回一个包含受生成 PGresult 的 SQL 语句影响的行数的字符串。此函数只能在执行 SELECTCREATE TABLE ASINSERTUPDATEDELETEMERGEMOVEFETCHCOPY 语句,或包含 INSERTUPDATEDELETEMERGE 语句的预处理查询的 EXECUTE 后使用。如果生成 PGresult 的命令是其他任何内容,则 PQcmdTuples 返回一个空字符串。调用者不应直接释放返回值。它将在关联 PGresult 句柄传递到 PQclear 时被释放。

    • PQoidValue #

  • 如果 SQL 命令是将一行确切地插入到有 OID 的表中或包含适当的 INSERT 语句的预处理查询的 EXECUTE,则返回插入行的 OID。否则,此函数返回 InvalidOid。如果 INSERT 语句影响的表不包含 OID,此函数也会返回 InvalidOid

Oid PQoidValue(const PGresult *res);
  • PQoidStatus #

    • 此函数已弃用,转而支持 PQoidValue ,且不是线程安全的。它返回一个包含插入行 OID 的字符串,而 PQoidValue 返回 OID 值。

char *PQoidStatus(const PGresult *res);

34.3.4. Escaping Strings for Inclusion in SQL Commands #

  • 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 对象中存储一条适当消息。

  • 请注意,当在 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 对象中存储一条适当消息。

    • 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 参数。正因如此,它无法根据连接属性(例如字符编码)调整其行为,因此 it might give the wrong results 。此外,它也没有报告错误条件的方法。

  • 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 使用 hex 编码或反斜杠转义转义字节。有关更多信息,请参阅 Section 8.4

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

  • PQescapeByteaConnfrom 参数二进制字符串的转义版本返回到使用 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 连接的客户端程序中安全地使用(在这种情况下,它可以“幕后”找出它需要了解的内容)。如果在使用多个数据库连接的程序中使用它,则会 might give the wrong results (在这种情况下使用 PQescapeByteaConn )。

    • PQunescapeBytea #

  • 将二进制数据的字符串表示形式转换为二进制数据—— PQescapeBytea 的逆过程。在以文本格式检索 bytea 数据时需要此,但在以二进制格式检索时不需要。

unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
  • from 参数指向一个字符串,例如 PQgetvalue 在应用于 bytea 列时可能返回的字符串。 PQunescapeBytea 将此字符串表示形式转换为其二进制表示形式。它返回指向使用 malloc() 分配的缓冲区的指针,或在出错时返回 NULL ,并将缓冲区的大小放入 to_length 中。不再需要结果时必须使用 PQfreemem 释放结果。

  • 此转换并非 PQescapeBytea 的确切逆过程,因为在从 PQgetvalue 接收时,预计字符串不会“转义”。特别是,这意味着无需考虑字符串引用,因此也无需 PGconn 参数。

Tip

在处理来自不受信任来源的字符串时,执行正确的转义操作尤其重要。否则存在安全风险:您容易受到“SQL 注入”攻击,其中不需要的 SQL 命令会传入您的数据库。

Tip

与字符串文字一样,为了防止 SQL 注入攻击,必须从不可信来源接收 SQL 标识符时对其进行转义。