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

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.1 已于 2006 年 4 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

第 1 章 libpq - C 库

libpq 是 Postgres 的 C 应用程序员接口。libpq 是一组库例程,客户端程序通过它们可以向 Postgres 后端服务器传送查询并接收这些查询的结果。libpq 也是其他几个 Postgres 应用接口的底层引擎,包括 libpq++(C++)、 libpgtcl(Tcl)、Perl 和 ecpg。因此,即使你使用的是上述某个软件包,libpq 行为的某些方面对你来说也很重要。

本节末尾包含三个简短程序,展示如何编写使用 libpq 的程序。下列目录中还有几个完整的 libpq 应用程序示例:

../src/test/regress
../src/test/examples
../src/bin/psql
   

使用 libpq 的前端程序必须包含头文件 libpq-fe.h,并且必须与 libpq 库链接。

1.1. 数据库连接函数 #

下面的例程用于建立与 Postgres 后端服务器的连接。一个应用程序可以同时打开多个后端连接(原因之一是需要访问多个数据库)。每个连接由一个 PGconn 对象表示,该对象通过 PQconnectdb 或 PQsetdbLogin 获得。注意,除非内存太少以至于连 PGconn 对象都无法分配,这些函数总是返回一个非空的对象指针。在通过连接对象发送查询之前,应当调用 PQstatus 函数检查连接是否成功建立。

  • PQconnectdb 与数据库服务器建立一个新连接。

    PGconn *PQconnectdb(const char *conninfo)
           
    

    此例程使用从字符串 conninfo 中取得的参数打开一个新的数据库连接。与下面的 PQsetdbLogin() 不同,该例程的参数集可以在不改变函数签名的情况下扩展,因此应用程序编程首选使用此例程或其非阻塞版本 PQconnectStart / PQconnectPoll。传入的字符串可以为空以使用全部默认参数,也可以包含一个或多个用空白分隔的参数设置。

    每个参数设置的形式为 keyword = value。(要写入空值或包含空格的值,请用单引号包围,例如 keyword = 'a value'。值中的单引号必须写作 \'。等号两边的空格是可选的。)目前可识别的参数关键字有:

    host

    要连接的主机名。如果它以斜杠开头,则表示使用 Unix 域通信而非 TCP/IP 通信;该值是存放套接字文件的目录名。默认连接到 /tmp 中的 Unix 域套接字。

    hostaddr

    要连接的主机的 IP 地址。其格式应为 BSD 函数 inet_aton 等使用的标准点分数字形式。如果指定了非零长度的字符串,则使用 TCP/IP 通信。

    使用 hostaddr 代替主机名可以让应用避免主机名查找,这对于有时间约束的应用可能很重要。但 Kerberos 认证需要主机名。因此适用以下规则。如果指定了主机名而没有指定 hostaddr,则强制进行主机名查找。如果指定了 hostaddr 而没有指定主机名,hostaddr 的值给出远程地址;若使用了 Kerberos,这会引起反向名称查询。如果主机名和 hostaddr 都被指定,hostaddr 的值给出远程地址;主机名的值被忽略,但使用 Kerberos 时例外,此时该值用于 Kerberos 认证。注意,如果传给 libpq 的主机名不是位于 hostaddr 的机器的名称,认证很可能失败。

    既没有主机名也没有主机地址时,libpq 将使用本地 Unix 域套接字连接。

    port

    服务器主机上要连接的端口号,或 Unix 域连接的套接字文件名扩展。

    dbname

    数据库名。

    user

    要以哪个用户名连接。

    password

    如果服务器要求密码认证则使用的密码。

    options

    要发送给服务器的跟踪/调试选项。

    tty

    用于后端可选调试输出的文件或 tty。

    requiressl

    设为 '1' 时要求与后端的 SSL 连接。如果服务器不支持 SSL,Libpq 将拒绝连接。设为 '0'(默认值)时与服务器协商。

    如果任何参数未指定,则检查相应的环境变量(见"环境变量"一节)。如果环境变量也未设置,则使用硬编码的默认值。返回值是指向一个抽象 struct 的指针,该结构表示到后端的连接。

  • PQsetdbLogin 与数据库服务器建立一个新连接。

    PGconn *PQsetdbLogin(const char *pghost,
                         const char *pgport,
                         const char *pgoptions,
                         const char *pgtty,
                         const char *dbName,
                         const char *login,
                         const char *pwd)
    

    这是 PQconnectdb 的前身,参数个数固定但功能相同。

  • PQsetdb 与数据库服务器建立一个新连接。

    PGconn *PQsetdb(char *pghost,
                    char *pgport,
                    char *pgoptions,
                    char *pgtty,
                    char *dbName)
    

    这是一个宏,以空指针作为 login 和 pwd 参数调用 PQsetdbLogin()。它主要是为了与旧程序保持向后兼容而保留。

  • PQconnectStart, PQconnectPoll 以非阻塞方式建立与数据库服务器的连接。

    PGconn *PQconnectStart(const char *conninfo)
    
    PostgresPollingStatusType PQconnectPoll(PGconn *conn)
    

    这两个例程用于打开到数据库服务器的连接,同时应用程序的执行线程不会在远程 I/O 上阻塞。

    数据库连接使用传给 PQconnectStart 的字符串 conninfo 中的参数建立。该字符串的格式与上面 PQconnectdb 中描述的相同。

    只要满足若干限制条件,PQconnectStart 和 PQconnectPoll 都不会阻塞:

    • 恰当地使用 hostaddr 和 host 参数,确保不进行(正向)名称和反向名称查询。详情见上面 PQconnectdb 下对这些参数的说明。

    • 如果调用 PQtrace,确保要写入跟踪信息的流对象不会阻塞。

    • 在调用 PQconnectPoll 之前,自行确保套接字处于适当的状态,如下所述。

    首先,调用 conn=PQconnectStart("<connection_info_string>")。如果 conn 为 NULL,说明 libpq 无法分配新的 PGconn 结构。否则返回一个有效的 PGconn 指针(尽管它尚未表示一个有效的数据库连接)。从 PQconnectStart 返回后,调用 status=PQstatus(conn)。如果 status 等于 CONNECTION_BAD,则 PQconnectStart 失败。

    如果 PQconnectStart 成功,下一阶段是轮询 libpq,使其继续进行连接序列。循环如下:默认将连接视为'非活跃'。如果 PQconnectPoll 上次返回了 PGRES_POLLING_ACTIVE,则改将其视为'活跃'。如果 PQconnectPoll(conn) 上次返回 PGRES_POLLING_READING,则在 PQsocket(conn) 上为读取执行 select。如果上次返回 PGRES_POLLING_WRITING,则在 PQsocket(conn) 上为写入执行 select。如果尚未调用过 PQconnectPoll(即刚调用完 PQconnectStart 之后),则视同它上次返回的是 PGRES_POLLING_WRITING。如果 select 表明套接字已就绪,将其视为'活跃'。一旦确定此连接处于'活跃'状态,就再次调用 PQconnectPoll(conn)。如果这次调用返回 PGRES_POLLING_FAILED,连接过程已失败。如果返回 PGRES_POLLING_OK,连接已成功建立。

    注意,用 select() 确保套接字就绪只是一个(常见的)例子;如果还有其他可用手段,例如 poll() 调用,当然可以改用它。

    在连接期间的任何时刻,都可以调用 PQstatus 检查连接状态。如果返回 CONNECTION_BAD,则连接过程已失败;如果返回 CONNECTION_OK,则连接已就绪。如上所述,这两种状态都应能从 PQconnectPoll 的返回值中同样检测到。其他状态只在(且仅会在)异步连接过程中出现,它们指示连接过程的当前阶段,例如可用于向用户提供反馈。这些状态可能包括:

    • CONNECTION_STARTED:等待建立连接。

    • CONNECTION_MADE:连接成功;等待发送。

    • CONNECTION_AWAITING_RESPONSE:等待 postmaster 的响应。

    • CONNECTION_AUTH_OK:已通过认证;等待后端启动。

    • CONNECTION_SETENV:正在协商环境。

    注意,尽管这些常量会保留(为了维护兼容性),应用程序绝不应依赖它们按特定顺序出现、依赖它们全都出现,或依赖状态总是这些已记录的值之一。应用程序可以这样处理:

        switch(PQstatus(conn))
        {
            case CONNECTION_STARTED:
                feedback = "Connecting...";
                break;
    
            case CONNECTION_MADE:
                feedback = "Connected to server...";
                break;
    .
    .
    .
            default:
                feedback = "Connecting...";
        }
    

    注意,如果 PQconnectStart 返回非 NULL 指针,使用完毕后必须调用 PQfinish,以释放该结构和所有关联的内存块。即使 PQconnectStart 或 PQconnectPoll 的调用失败,也必须这样做。

    当前,如果 libpq 编译时定义了 USE_SSL,PQconnectPoll 会阻塞。此限制将来可能被移除。

    当前,在 Windows 下 PQconnectPoll 会阻塞,除非 libpq 编译时定义了 WIN32_NON_BLOCKING_CONNECTIONS。这段代码尚未在 Windows 下测试过,因此目前默认关闭。将来可能改变。

    这些函数会把套接字置于非阻塞状态,就像调用过 PQsetnonblocking 一样。

  • PQconndefaults 返回默认的连接选项。

    PQconninfoOption *PQconndefaults(void)
    
    struct PQconninfoOption
    {
        char   *keyword;   /* The keyword of the option */
        char   *envvar;    /* Fallback environment variable name */
        char   *compiled;  /* Fallback compiled in default value */
        char   *val;       /* Option's current value, or NULL */
        char   *label;     /* Label for field in connect dialog */
        char   *dispchar;  /* Character to display for this field
                              in a connect dialog. Values are:
                              ""        Display entered value as is
                              "*"       Password field - hide value
                              "D"       Debug option - don't show by default */
        int     dispsize;  /* Field size in characters for dialog */
    }
    

    返回一个连接选项数组。它可用来确定 PQconnectdb 的所有可用选项及其当前默认值。返回值指向一个 PQconninfoOption struct 数组,该数组以一个 keyword 指针为 NULL 的条目结尾。注意,默认值("val" 字段)依赖于环境变量和其他上下文。调用者必须将连接选项数据视为只读。

    处理完选项数组后,将它传递给 PQconninfoFree() 释放。如果不这样做,每次调用 PQconndefaults() 都会泄漏少量内存。

    在 Postgres 7.0 之前的版本中,PQconndefaults() 返回指向静态数组的指针,而不是动态分配的数组。那样不是线程安全的,因此行为已被改变。

  • PQfinish 关闭与后端的连接,同时释放 PGconn 对象使用的内存。

    void PQfinish(PGconn *conn)
    

    注意,即使与后端的连接尝试失败(由 PQstatus 指示),应用也应调用 PQfinish 释放 PGconn 对象使用的内存。调用过 PQfinish 之后,不应再使用该 PGconn 指针。

  • PQreset 重置与后端的通信端口。

    void PQreset(PGconn *conn)
    

    此函数将关闭与后端的连接,并尝试使用先前使用的全部相同参数与同一个 postmaster 重新建立新连接。如果工作中的连接丢失,这可用于错误恢复。

  • PQresetStart PQresetPoll 以非阻塞方式重置与后端的通信端口。

    int PQresetStart(PGconn *conn);
    
    PostgresPollingStatusType PQresetPoll(PGconn *conn);
    

    这些函数将关闭与后端的连接,并尝试使用先前使用的全部相同参数与同一个 postmaster 重新建立新连接。如果工作中的连接丢失,这可用于错误恢复。它们与上面的 PQreset 的不同之处在于以非阻塞方式运作。这些函数受到与 PQconnectStart 和 PQconnectPoll 相同的限制。

    调用 PQresetStart。如果返回 0,重置失败。如果返回 1,用与使用 PQconnectPoll 建立连接完全相同的方式,使用 PQresetPoll 对重置进行轮询。

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

  • PQdb 返回连接的数据库名。

    char *PQdb(const PGconn *conn)
    

    PQdb 及其后面几个函数返回在建立连接时确定的值。这些值在 PGconn 对象的整个生命周期内保持不变。

  • PQuser 返回连接的用户名。

    char *PQuser(const PGconn *conn)
    
  • PQpass 返回连接的密码。

    char *PQpass(const PGconn *conn)
    
  • PQhost 返回连接的服务器主机名。

    char *PQhost(const PGconn *conn)
    
  • PQport 返回连接的端口。

    char *PQport(const PGconn *conn)
    
  • PQtty 返回连接的调试 tty。

    char *PQtty(const PGconn *conn)
    
  • PQoptions 返回连接中使用的后端选项。

    char *PQoptions(const PGconn *conn)
    
  • PQstatus 返回连接的状态。

    ConnStatusType PQstatus(const PGconn *conn)
    

    状态可以是若干值之一。但在异步连接过程之外只能见到其中两个—— CONNECTION_OK 或 CONNECTION_BAD。正常的数据库连接状态为 CONNECTION_OK。失败的连接尝试由状态 CONNECTION_BAD 表示。通常,OK 状态会一直保持到调用 PQfinish 为止,但通信故障可能导致状态提前变为 CONNECTION_BAD。此时应用可以尝试调用 PQreset 来恢复。

    关于可能见到的其他状态码,参见 PQconnectStart 和 PQconnectPoll 的条目。

  • PQerrorMessage 返回连接上最近一次操作所产生的错误消息。

    char *PQerrorMessage(const PGconn* conn);
           
    

    几乎所有 libpq 函数在失败时都会设置 PQerrorMessage。注意,按照 libpq 的惯例,非空的 PQerrorMessage 会包含一个末尾换行符。

  • PQbackendPID 返回处理此连接的后端服务器的进程 ID。

    int PQbackendPID(const PGconn *conn);
           
    

    后端 PID 可用于调试,也可用于与 NOTIFY 消息(其中包含发出通知的后端的 PID)进行比较。注意,该 PID 属于数据库服务器主机上执行的进程,而不是本地主机上的进程!

  • PQgetssl 返回连接中使用的 SSL 结构;若未使用 SSL 则返回 NULL。

    SSL *PQgetssl(const PGconn *conn);
           
    

    此结构可用于核实加密级别、检查服务器证书等。有关此结构的信息,请参阅 OpenSSL 文档。

    必须定义 USE_SSL 才能获得此函数的原型。这样做还会自动包含来自 OpenSSL 的 ssl.h。

  • PQgetssl 返回连接中使用的 SSL 结构;若未使用 SSL 则返回 NULL。

    SSL *PQgetssl(const PGconn *conn);
           
    

    此结构可用于核实加密级别、检查服务器证书等。有关此结构的信息,请参阅 OpenSSL 文档。

    必须定义 USE_SSL 才能获得此函数的原型。这样做还会自动包含来自 OpenSSL 的 ssl.h。

提交更正

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