↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 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
历史版本PostgreSQL 7.3 已于 2007 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

1.3. 命令执行函数 #

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

1.3.1. 主要例程 #

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

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

    返回一个 PGresult 指针,也可能返回 NULL 指针。除内存耗尽或无法将命令发送到后端等严重错误外,一般会返回非 NULL 指针。如果返回了 NULL,应将其视同 PGRES_FATAL_ERROR 结果。使用 PQerrorMessage 获取该错误的更多信息。

PGresult 结构封装了后端返回的结果。 libpq 应用程序员应注意维护 PGresult 的抽象。请使用下面的访问函数获取 PGresult 的内容。避免直接引用 PGresult 结构的字段,因为它们将来可能改变。(从 PostgreSQL 6.4 开始,libpq-fe.h 中甚至不再提供 struct PGresult 的定义。如果你有直接访问 PGresult 字段的旧代码,可以通过同时包含 libpq-int.h 继续使用它,但我们建议你尽快修改这些代码。)

  • PQresultStatus 返回命令的结果状态。

    ExecStatusType PQresultStatus(const PGresult *res)
    

    PQresultStatus 可以返回下列值之一:

    • PGRES_EMPTY_QUERY —— 发送给后端的字符串为空。

    • PGRES_COMMAND_OK —— 不返回数据的命令成功完成

    • PGRES_TUPLES_OK —— 查询成功执行

    • PGRES_COPY_OUT —— Copy Out(从服务器传出)数据传输已开始

    • PGRES_COPY_IN —— Copy In(向服务器传入)数据传输已开始

    • PGRES_BAD_RESPONSE —— 无法理解服务器的响应

    • PGRES_NONFATAL_ERROR

    • PGRES_FATAL_ERROR

    如果结果状态为 PGRES_TUPLES_OK,就可以使用下面描述的例程检索查询返回的行。注意,碰巧检索到零行的 SELECT 命令仍然显示 PGRES_TUPLES_OK。PGRES_COMMAND_OK 用于永远不会返回行的命令(INSERT、UPDATE 等)。PGRES_EMPTY_QUERY 响应往往暴露客户端软件中的 bug。

  • PQresStatus 把 PQresultStatus 返回的枚举类型转换为描述该状态码的字符串常量。

    char *PQresStatus(ExecStatusType status);
    
  • PQresultErrorMessage 返回与查询相关联的错误消息;如果没有错误则返回空字符串。

    char *PQresultErrorMessage(const PGresult *res);
    

    在 PQexec 或 PQgetResult 调用之后紧接着,(连接上的)PQerrorMessage 会返回与(结果上的)PQresultErrorMessage 相同的字符串。但 PGresult 会保留其错误消息直到被销毁,而连接的错误消息会随后续操作而变化。想知道与某个特定 PGresult 相关联的状态时使用 PQresultErrorMessage;想知道连接上最新操作的状态时使用 PQerrorMessage。

  • PQclear 释放与 PGresult 关联的存储。每个查询结果在不再需要时都应通过 PQclear 释放。

    void PQclear(PQresult *res);
    

    PGresult 对象需要保留多久就可以保留多久;发出新查询时它不会消失,即使关闭连接也不会。要清除它,必须调用 PQclear。不这样做将导致前端应用内存泄漏。

  • PQmakeEmptyPGresult 以给定的状态构造一个空的 PGresult 对象。

    PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
    

    这是 libpq 分配并初始化空 PGresult 对象的内部例程。导出它是因为某些应用发现自己生成结果对象(特别是带有错误状态的对象)很有用。如果 conn 非 NULL 且 status 指示一个错误,连接的当前错误消息会被复制到 PGresult. 注意,最终也应对该对象调用 PQclear,就像对待 libpq 本身返回的 PGresult 一样。

1.3.2. 用于在 SQL 命令中嵌入字符串的转义 #

PQescapeStringConn为了让一个字符串可用于 SQL 命令而对它进行转义。当在 SQL 命令中把数据值作为字符串字面量插入时,这很有用。一些字符(例如引号和反斜杠)必须经过转义,才不会被 SQL 解析器解释成特殊含义。PQescapeStringConn执行这种操作。

提示

在处理来自不可信来源的字符串时,正确转义尤其重要。否则就会有安全风险:你很容易受到“SQL 注入”攻击,不期望的 SQL 命令可能会被送入数据库。

size_t PQescapeStringConn (PGconn *conn,
                           char *to, const char *from, size_t length,
                           int *error);

PQescapeStringConn把from字符串的转义版本写入to缓冲区,对特殊字符进行转义使它们不会造成任何危害,并添加一个终止的零字节。包围PostgreSQL字符串字面量所需的单引号不包含在结果字符串中;它们应在插入转义结果的 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);

PQescapeString是PQescapeStringConn的一个较老的、已弃用的版本;区别在于它不接受conn或error参数。因此,它无法根据连接属性(例如字符编码)调整行为,可能给出错误的结果。此外,它也无法报告错误情况。

PQescapeString可以在同一时刻仅使用一个PostgreSQL连接的单线程客户端程序中安全使用(在这种情况下,它能够“在内部”取得所需信息)。在其他情形下,它存在安全隐患,应改用PQescapeStringConn。

1.3.3. 用于在 SQL 命令中嵌入二进制串的转义 #

PQescapeByteaConn

对二进制数据进行转义,使其可用于带 bytea 类型的 SQL 命令。

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

在 SQL 语句中作为 bytea 字面量的一部分使用时,某些字节值必须转义(但所有字节值都可以转义)。一般而言,转义一个字节时,把它转换为等于该字节值的八进制三位数,并在前面加一个或两个反斜杠。单引号(')和反斜杠( \)字符有特殊的替代转义序列。PQescapeByteaConn 执行此操作,只对最少必需的字节进行转义。

from 参数指向待转义字符串的首字节,from_length 参数给出该二进制字符串的字节数。(末尾零字节既不需要,也不计入长度。)to_length 参数指向用于保存转义后字符串长度的变量。该结果字符串长度包含结果末尾的零字节。

PQescapeByteaConn 返回 from 参数二进制字符串的转义版本,存放在用 malloc() 分配的内存中。结果不再需要时,必须用 free() 释放该内存。返回字符串中的所有特殊字符都已替换,使 PostgreSQL 字符串字面量解析器和 bytea 输入函数能正确处理它们。还会添加一个终止零字节。包围 PostgreSQL 字符串字面量所必需的单引号不是结果字符串的一部分。

在发生错误时,将返回一个空指针,并且一个合适的错误消息被存储在conn对象中。当前,唯一可能的错误是没有足够的内存用于结果串。

PQescapeBytea

PQescapeBytea 是 PQescapeByteaConn 的较老且已弃用的版本。

unsigned char *PQescapeBytea(unsigned char *from,
                             size_t from_length,
                             size_t *to_length);

与 PQescapeByteaConn 唯一的区别是 PQescapeBytea 不接受 PGconn 参数。因此,它无法根据连接属性调整行为,可能给出错误的结果。此外,它也无法在失败时返回错误消息。

PQescapeBytea 可以在同一时刻仅使用一个 PostgreSQL 连接的单线程客户端程序中安全使用(在这种情况下,它能够“在内部”取得所需信息)。在其他情形下,它存在安全隐患,应改用 PQescapeByteaConn。

PQunescapeBytea

把二进制数据的字符串表示转换为二进制数据——即 PQescapeBytea 的逆操作。以文本格式检索 bytea 数据时需要此函数;以二进制格式检索时则不需要。

unsigned char *PQunescapeBytea(unsigned char *from, size_t *to_length);

from 参数指向一个字符串,例如对 bytea 列调用 PQgetvalue 时返回的字符串。PQunescapeBytea 将这个字符串表示转换为二进制表示。它返回指向用 malloc() 分配的缓冲区的指针,出错时返回空,并将缓冲区大小存入 to_length。不再需要结果时,必须用 free() 释放它。

此转换并不完全是PQescapeBytea的逆操作,因为从PQgetvalue收到的字符串并非经过“转义”的形式。 具体而言,这意味着无需考虑字符串引号,因此也不需要PGconn参数。

1.3.4. 检索 SELECT 结果信息 #

  • PQntuples 返回查询结果中的元组(行)数。

    int PQntuples(const PGresult *res);
    
  • PQnfields 返回查询结果中每一行的字段(列)数。

    int PQnfields(const PGresult *res);
    
  • PQfname 返回与给定字段下标相关联的字段(列)名。字段下标从 0 开始。

    char *PQfname(const PGresult *res,
                        int field_index);
    
  • PQfnumber 返回与给定字段名相关联的字段(列)下标。

    int PQfnumber(const PGresult *res,
                  const char *field_name);
    

    如果给定的名称不匹配任何字段,返回 -1。

  • PQftype 返回与给定字段下标相关联的字段类型。返回的整数是该类型的内部编码。字段下标从 0 开始。

    Oid PQftype(const PGresult *res,
                int field_index);
    

    可以查询系统表 pg_type 来获取各种数据类型的名称和属性。内置数据类型的 OID 定义在源码树的 src/include/catalog/pg_type.h 文件中。

  • PQfmod 返回与给定字段下标相关联的字段的类型专属修饰数据。字段下标从 0 开始。

    int PQfmod(const PGresult *res,
               int field_index);
    
  • PQfsize 返回与给定字段下标相关联的字段的大小,以字节计。字段下标从 0 开始。

    int PQfsize(const PGresult *res,
                int field_index);
    

    PQfsize 返回数据库元组中为该字段分配的空间,换句话说,即服务器对该数据类型的二进制表示的大小。如果字段是变长的则返回 -1。

  • PQbinaryTuples 如果 PGresult 包含二进制元组数据则返回 1,包含 ASCII 数据则返回 0。

    int PQbinaryTuples(const PGresult *res);
    

    目前,只有从二进制游标提取数据的查询才能返回二进制元组数据。

1.3.5. 检索 SELECT 结果值 #

  • PQgetvalue 返回 PGresult 中某个元组(行)的单个字段(列)值。元组和字段下标都从 0 开始。

    char* PQgetvalue(const PGresult *res,
                     int tup_num,
                     int field_num);
    

    对大多数查询而言,PQgetvalue 返回的是属性值的以空字符结尾的字符串表示。但如果 PQbinaryTuples() 为 1,PQgetvalue 返回的就是该类型以后端服务器内部格式表示的二进制表示(若字段为变长则不含大小字)。此时由程序员负责把数据转换成正确的 C 类型。PQgetvalue 返回的指针指向属于 PGresult 结构的存储空间。不应修改它;如果需要在 PGresult 结构的生命周期结束后继续使用该值,就必须显式地将它复制到其他存储空间。

  • PQgetisnull 测试一个字段是否为 NULL 条目。元组和字段下标从 0 开始。

    int PQgetisnull(const PGresult *res,
                    int tup_num,
                    int field_num);
    

    如果字段包含 NULL,此函数返回 1;包含非 NULL 值则返回 0。(注意,对于 NULL 字段,PQgetvalue 返回的是空字符串而不是空指针。)

  • PQgetlength 返回字段(属性)值的长度,以字节计。元组和字段下标从 0 开始。

    int PQgetlength(const PGresult *res,
                    int tup_num,
                    int field_num);
    

    这是该特定数据值的实际数据长度,即 PQgetvalue 所指对象的大小。注意,对于以字符表示的值,此大小与 PQfsize 报告的二进制大小几乎没有关系。

  • PQprint 打印出所有的元组以及(可选的)属性名到指定的输出流。

    void PQprint(FILE* fout,      /* output stream */
                 const PGresult *res,
                 const PQprintOpt *po);
    
    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;   /* insert to HTML table ... */
        char    *caption;    /* HTML caption */
        char    **fieldName; /* null terminated array of replacement field names */
    } PQprintOpt;
           
    

    此函数以前被 psql 用于打印查询结果,但现在已不再如此,此函数也不再被积极维护。

1.3.6. 检索非 SELECT 结果信息 #

  • PQcmdStatus 返回生成该 PGresult 的 SQL 命令的命令状态字符串。

    char * PQcmdStatus(PGresult *res);
    
  • PQcmdTuples 返回受 SQL 命令影响的行数。

    char * PQcmdTuples(PGresult *res);
    

    如果生成该 PGresult 的 SQL 命令是 INSERT、UPDATE 或 DELETE,此函数返回一个包含受影响行数的字符串。如果是其他命令,返回空字符串。

  • PQoidValue 如果 SQL 命令是一个向带 OID 的表中恰好插入一行的 INSERT,返回所插入行的对象 ID。否则返回 InvalidOid。

    Oid PQoidValue(const PGresult *res);
    

    包含 libpq 头文件后,将定义类型 Oid 和常量 InvalidOid。它们都属于某种整数类型。

  • PQoidStatus 如果 SQL 命令是一个 INSERT,返回一个含有所插入行对象 ID 的字符串。(如果该 INSERT 并非恰好插入一行,或目标表不带 OID,字符串为 0。)如果命令不是 INSERT,返回空字符串。

    char * PQoidStatus(const PGresult *res);
    

    此函数已被弃用,由 PQoidValue 取代,且不是线程安全的。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。