LXXXIV. PostgreSQL 数据库函数库

介绍

PostgreSQL 是一个开放源码的免费数据库系统。Postgres 最初由加州大学伯克利分校计算机科学系开发,倡导了很多关系对象的观念,这些观念现在已经用在一些商业数据库系统中。它提供了 SQL92/SQL99 语言支持,事务处理,引用集成,存储过程以及类型扩展。PostgreSQL 则是 Postgres 的一个开放源代码的后代。

需求

要使用 PostgreSQL 支持,需要 PostgreSQL 6.5 或更新版本,PostgreSQL 7.0 或更新版本来使用所有的 PostgreSQL 模块。PostgreSQL 支持多种字符编码包括多字节字符编码。关于 PostgreSQL 的当前版本以及更多信息见 http://www.postgresql.org/ 以及 http://techdocs.postgresql.org/

安装

为添加 PostgreSQL 支持,在编译 PHP 时需要加上 --with-pgsql[=DIR] 选项。如果可以用共享模块方式,PostgreSQL 模块可以在 php.iniextension 指令或者 dl() 函数加载。

运行时配置

这些函数的行为受到全局配置文件 php.ini 的影响。

表格 1. PostgreSQL 配置选项

名称默认值可变范围
pgsql.allow_persistent"1"PHP_INI_SYSTEM
pgsql.max_persistent"-1"PHP_INI_SYSTEM
pgsql.max_links"-1"PHP_INI_SYSTEM
pgsql.auto_reset_persistent"0"PHP_INI_SYSTEM
pgsql.ignore_notice"0"PHP_INI_ALL
pgsql.log_notice"0"PHP_INI_ALL
PHP_INI_* 常量的更多细节和定义参见 ini_set()

以下是该配置选项的简要解释。

pgsql.allow_persistent boolean

是否允许持久的 Postgres 连接。

pgsql.max_persistent integer

每个进程所能有的持久 Postgres 连接数目。

pgsql.max_links integer

每个进程所能有的 Postgres 连接数目,包括持久连接。

pgsql.auto_reset_persistent integer

检测用在 pg_pconnect() 上的中断了的持久连接。需要一些损耗。

pgsql.ignore_notice integer

是否忽略 PostgreSQL 后端的通告。

pgsql.log_notice integer

是否记录 PostgreSQL 后端的通告消息。要记录通告消息日志,PHP 指令 pgsql.ignore_notice 必须为 off。

使用方法及提示

警告

由于 notice message handling 代码中的 bug,不推荐在 PHP 4.0.6 中使用 PostgreSQL 模块。使用 4.1.0 或更新版本。

警告

为符合当前编码标准,PostgreSQL 函数名称将在 4.2.0 版本中改变。大多数新名称将多出一个下划线,例如 pg_lo_open()。一部分函数则改变了名称以保持一致性。例如 pg_exec() 改为 pg_query()。老的函数名依然可以在 4.2.0 和以后的少数几个版本中使用,但以后可能会删除。

表格 2. 已改变的函数名

旧名称新名称
pg_exec()pg_query()
pg_getlastoid()pg_last_oid()
pg_cmdtuples()pg_affected_rows()
pg_numrows()pg_num_rows()
pg_numfields()pg_num_fields()
pg_fieldname()pg_field_name()
pg_fieldsize()pg_field_size()
pg_fieldnum()pg_field_num()
pg_fieldprtlen()pg_field_prtlen()
pg_fieldisnull()pg_field_is_null()
pg_freeresult()pg_free_result()
pg_result()pg_fetch_result()
pg_loreadall()pg_lo_read_all()
pg_locreate()pg_lo_create()
pg_lounlink()pg_lo_unlink()
pg_loopen()pg_lo_open()
pg_loclose()pg_lo_close()
pg_loread()pg_lo_read()
pg_lowrite()pg_lo_write()
pg_loimport()pg_lo_import()
pg_loexport()pg_lo_export()

为以后支持异步连接,将不再提倡用旧语法使用函数 pg_connect()/pg_pconnect()。请用连接字符串作为参数来使用函数 pg_connect()pg_pconnect()

不是所有的版本都支持所有的函数,这和 libpq 的版本和编译方法有关。如果编译源代码时少了一个函数,那么 libpq 就不支持需要该函数的功能。

不要使用比 PostgreSQL 服务器连接所接受更旧版本的 libpq 也很重要。如果你用的 libpq 版本比 PostgreSQL 服务器预期的低就可能出现问题。

PostgreSQL 在 6.3 (03/02/1998) 版之后默认使用 unix domain sockets,默认状态下不会打开 TCP 端口。下面这张表说明了各种新建连接的可能性。TCP/IP socket 放在 /tmp/.s.PGSQL.5432。该选项可用 postmaster 中的 '-i' 参数打开,它表示“监视 TCP/IP 端口以及 Unix domain socket”。

表格 3. Postmaster 和 PHP

PostmasterPHP状态
postmaster &pg_connect("dbname=MyDbName");OK
postmaster -i &pg_connect("dbname=MyDbName");OK
postmaster &pg_connect("host=localhost dbname=MyDbName"); Unable to connect to PostgreSQL server: connectDB() failed: Is the postmaster running and accepting TCP/IP (with -i) connection at 'localhost' on port '5432'? in /path/to/file.php on line 20.
postmaster -i &pg_connect("host=localhost dbname=MyDbName");OK

到 PostgreSQL 服务器的连接可以通过以下命令串中的参数对建立:$conn = pg_connect("host=myHost port=myPort tty=myTTY options=myOptions dbname=myDB user=myUser password=myPassword");

以前的语法: $conn = pg_connect ("host", "port", "options", "tty", "dbname") 已经不再提倡使用。

环境变量会影响 PostgreSQL 服务器/客户机的行为。例如如果连接串中省略了主机名,PostgreSQL 模块将会查找环境变量 PGHOST。 不同版本所支持的环境变量不同,详情参考 PostgreSQL Programmers's Manual (libpq - Environment Variables)。

确认已经给适当的用户设置了环境变量。用 $_ENVgetenv() 来检查当前进程可以使用哪些环境变量。

例子 1. 设定默认参数

PGHOST=pgsql.example.com
PGPORT=7890
PGDATABASE=web-system
PGUSER=web-user
PGPASSWORD=secret
PGDATESTYLE=ISO
PGTZ=JST
PGCLIENTENCODING=EUC-JP

export PGHOST PGPORT PGDATABASE PGUSER PGPASSWORD PGDATESTYLE PGTZ PGCLIENTENCODING

预定义常量

由于这些常量是由该扩展模块定义的,因此只有在该扩展模块被编译到 PHP 中,或者在运行时被动态加载后,这些常量才有效。

PGSQL_ASSOC (integer)

PGSQL_NUM (integer)

PGSQL_BOTH (integer)

PGSQL_CONNECTION_BAD (integer)

PGSQL_CONNECTION_OK (integer)

PGSQL_SEEK_SET (integer)

PGSQL_SEEK_CUR (integer)

PGSQL_SEEK_END (integer)

PGSQL_ESCAPE_STRING (integer)

PGSQL_ESCAPE_BYTEA (integer)

PGSQL_EMPTY_QUERY (integer)

PGSQL_COMMAND_OK (integer)

PGSQL_TUPLES_OK (integer)

PGSQL_COPY_OUT (integer)

PGSQL_COPY_IN (integer)

PGSQL_BAD_RESPONSE (integer)

PGSQL_NONFATAL_ERROR (integer)

PGSQL_FATAL_ERROR (integer)

范例

从 PostgreSQL 7.1.0 开始,在一个 text 类型字段中最多可以储存 1GB 的数据。在老版本中则限制为一个块的大小(默认 8KB,最大 32KB,编译时指定)。

要使用 large object (lo) 接口,需要把 large object 函数放在一个事务段中。事务段以 SQL 语句 BEGIN 开始,如果该事务合法,以 COMMIT 或者 END结束,如果该事务失败,则以 ROLLBACK 或者 ABORT结束。

例子 2. 使用 Large Object

<?php
    $database
= pg_connect ("dbname=jacarta");
    
pg_query ($database, "begin");
    
$oid = pg_lo_create ($database);
    echo
"$oid\n";
    
$handle = pg_lo_open ($database, $oid, "w");
    echo
"$handle\n";
    
pg_lo_write ($handle, "large object data");
    
pg_lo_close ($handle);
    
pg_query ($database, "commit");
?>
在关闭 large object 之前不应关闭到 PostgreSQL 服务器的连接。

目录
pg_affected_rows -- 返回受影响的记录数目
pg_cancel_query --  取消异步查询
pg_client_encoding --  取得客户端编码方式
pg_close -- 关闭一个 PostgreSQL 连接
pg_connect -- 打开一个 PostgreSQL 连接
pg_connection_busy --  获知连接是否为忙
pg_connection_reset --  重置连接(再次连接)
pg_connection_status --  获得连接状态
pg_convert --  将关联的数组值转换为适合 SQL 语句的格式。
pg_copy_from --  根据数组将记录插入表中
pg_copy_to --  将一个表拷贝到数组中
pg_dbname -- 获得数据库名
pg_delete --  删除记录
pg_end_copy -- 与 PostgreSQL 后端同步
pg_escape_bytea --  转义 bytea 类型的二进制数据
pg_escape_string --  转义 text/char 类型的字符串
pg_fetch_all -- 从结果中提取所有行作为一个数组
pg_fetch_array -- 提取一行作为数组
pg_fetch_assoc -- 提取一行作为关联数组
pg_fetch_object -- 提取一行作为对象
pg_fetch_result -- 从结果资源中返回值
pg_fetch_row -- 提取一行作为枚举数组
pg_field_is_null -- 测试字段是否为 NULL
pg_field_name -- 返回字段的名字
pg_field_num -- 返回字段的编号
pg_field_prtlen -- 返回打印出来的长度
pg_field_size --  返回指定字段占用内部存储空间的大小
pg_field_type --  返回相应字段的类型名称
pg_free_result -- 释放查询结果占用的内存
pg_get_notify -- Ping 数据库连接
pg_get_pid -- Ping 数据库连接
pg_get_result --  取得异步查询结果
pg_host --  返回和某连接关联的主机名
pg_insert --  将数组插入到表中
pg_last_error -- 得到某连接的最后一条错误信息
pg_last_notice --  返回 PostgreSQL 服务器最新一条公告信息
pg_last_oid -- 返回上一个对象的 oid
pg_lo_close -- 关闭一个大型对象
pg_lo_create -- 新建一个大型对象
pg_lo_export -- 将大型对象导出到文件
pg_lo_import -- 将文件导入为大型对象
pg_lo_open -- 打开一个大型对象
pg_lo_read_all --  读入整个大型对象并直接发送给浏览器
pg_lo_read -- 从大型对象中读入数据
pg_lo_seek --  移动大型对象中的指针
pg_lo_tell --  返回大型对象的当前指针位置
pg_lo_unlink -- 删除一个大型对象
pg_lo_write -- 向大型对象写入数据
pg_metadata --  获得表的元数据
pg_num_fields -- 返回字段的数目
pg_num_rows -- 返回行的数目
pg_options -- 获得和连接有关的选项
pg_pconnect -- 打开一个持久的 PostgreSQL 连接
pg_ping -- Ping 数据库连接
pg_port --  返回该连接的端口号
pg_put_line -- 向 PostgreSQL 后端发送以 NULL 结尾的字符串
pg_query -- 执行查询
pg_result_error --  获得查询结果的错误信息
pg_result_seek -- 在结果资源中设定内部行偏移量
pg_result_status --  获得查询结果的状态
pg_select --  选择记录
pg_send_query --  发送异步查询
pg_set_client_encoding --  设定客户端编码
pg_trace -- 启动一个 PostgreSQL 连接的追踪功能
pg_tty --  返回该连接的 tty 号
pg_unescape_bytea --  取消 bytea 类型中的字符串转义
pg_untrace -- 关闭 PostgreSQL 连接的追踪功能
pg_update --  更新表