Next Previous Contents

11. PostgreSQL 的 Perl 资料库介面 (Database Interface, DBI)

11.1 PostgreSQL 的 PERL 5 介面

PERL 是‘Practical Exptraction and Report Language’的简写。世上所有软硬件平台都可使用 Perl。你所在视窗 95/NT、苹果麦金塔 iMac、所有 Unix (Solaris、HPUX、AIX、Linux、Irix、SCO 等等)、大型电脑 MVS、桌面的 OS/2、OS/400、Amdahl UTS 和其他很多电脑。Perl 甚至可在很多不流行和不为人知的操作系统和硬件执行!!所以,在看到 Perl 在一个罕见的操作系统上执行时,不必大惊小怪。你可以想像到 Perl 的使用者和开发人员的数量。

PostgreSQL 的 Perl 介面已包括在 PostgreSQL 的散布中。请参看 src/pgsql_perl5 目录。

11.2 Perl 资料库介面 DBI

何谓 DBI?

Perl 资料库介面(DBI)是 Perl 语言的一个资料库存取应用程式介面(API)。Perl DBI API 规格定义了一组函数、变数和惯例,以提供一个一致而独立於实际所用的资料库介面。有关 DBI 的这一段的资料是来自‘DBI FAQ’文件,作者是 Alligator Descartes,并获准在此复制。

PostgreSQL 的 DBI 驱动程式 DBD-Pg-0.89

在此取得 DBD-Pg-0.89.tar.gz∶

系统需求∶

DBI 的技术支援

请把意见和错误报告寄到

请把以 perl -v、perl -V 的输出、PostgreSQL 的版本、DBD-Pg 的版本、DBI 的版本包括在错误报告中。

何谓 DBI、DBperl、Oraperl 和 *perl?

摘录自 Tim Bunce,DBI 的设计者和作者∶

“DBI 是 Perl 语言的一种应用程式介面(API)。Perl DBI API 规格定义了 一组函数、变数和惯例,用於提供一个一致而独立於实际所用的资料库介面。”

简单地说,DBI 容许用家透明地 (transparently) 存取多种资料库。所以,如果你连接到 Oracle、Informix、mSQL、Sybase 或任何资料库,你不需要知道 3GL 层面内里的机制。DBI 所定义的 API 可用於所有这些资料库。

这样的好处是你得到在一篇 perl 手稿中连接两个不同出版商不同的资料库,例如在一个程式中读取在一个 Oracle 资料库的资料及将它插入到 Informix 资料库中。DBI 层面容许你简单及有力地做到。

DBperl 是这个介面规格的旧名。它现在一般用於代表用於 perl4 的资料库介面模组,如 oraperl、isqlperl、ingperl 之类。这些介面没有标准的 API,一般已没有支援。

这是 DBperl 模组的名单,所对应的 DBI 模组及技术支援资讯。有关 DBI 驱动程式的问题应该在 dbi-users 通讯论坛提出。 list.

     模组名称      所需资料库        作者           DBI
    ----------- -----------------   ------          ---
    Sybperl     Sybase              Michael Peppler DBD::Sybase
                                    <mpeppler@datamig.com>
                                    http://www.mbay.net/~mpeppler
    Oraperl     Oracle 6 & 7        Kevin Stock     DBD::Oracle
                                    <dbi-users@fugue.com>
    Ingperl     Ingres              Tim Bunce &     DBD::Ingres
                                    Ted Lemon
                                    <dbi-users@fugue.com>
    Interperl   Interbase           Buzz Moschetti  DBD::Interbase
                                    <buzz@bear.com>
    Uniperl     Unify 5.0           Rick Wargo      None
                                    <rickers@coe.drexel.edu>
    Pgperl      Postgres            Igor Metz       DBD::Pg
                                    <metz@iam.unibe.ch>
    Btreeperl   NDBM                John Conover    SDBM?
                                    <john@johncon.com>
    Ctreeperl   C-Tree              John Conover    None
                                    <john@johncon.com>
    Cisamperl   Informix C-ISAM     Mathias Koerber None
                                    <mathias@unicorn.swi.com.sg>
    Duaperl     X.500 Directory     Eric Douglas    None
                User Agent
不过,部分 DBI 模组有 DBperl 模拟层 (emulation layers),因此,DBD:Oracle 会有 Oraperl 模拟层,让你无需更改现存的 Oraperl 手稿便能执行。这模拟层把 Oraperl API 呼叫翻译成 DBI 呼叫并通过 DBI 执行。

这列表是模拟层的资料∶

    模组            模拟层              状况
    ------          ---------------     ------
    DBD::Oracle     Oraperl             完成
    DBD::Informix   Isqlperl            开发中
    DBD::Sybase     Sybperl             可用?(有待验证)
    DBD::mSQL       Msqlperl            在 DBD::mSQL-0.61 中实验性推出
Msqlperl 模拟是特殊情况。Msqlperl 是 mSQL 资料库的 perl5 驱动程式,但不依从 DBI 规格。大家应使用 DBD::mSQL,而不应用 Msqlperl。Msqlperl 可从 CPAN 下载∶

DBI 规格

这里有一些 DBI 的资料来源。

这会连结到二个规格,即开发队伍努力发展一个稳定的介面期间,正快速更改的新 DBI 规格草案,和旧 DBperl 规格发展而来,目前的 DBI 介面。

後者应只被视为历史纪录,而不可用作程式设计说明书或任何具权威性的文件。不过,它还是十分有用的参考资料。

POD 文件 POD 是嵌入到 perl 程式中用以“即场”解释程式码的一段文件,用以提供 有用的资料给程式设计师和模组的用家。DBI 和驱动程式的 POD 正越来越流行,要阅读有关文件,请使用以下指令。

DBI 规格 请使用以下指令阅读 DBI 规格的 POD

perldoc DBI

Oraperl DBD::Oracle 中 Oraperl 模拟层的使用者可用以下指令学习如何用 Oraperl 介面编写程式∶

perldoc Oraperl

这样会产生一份由 Kevin Stock 为 perl4 所写的原装 oraperl man page 更新版。这里会全面列出及介绍 oraperl API。

DBD::mSQL DBD::mSQL 模组的用家可籍以下指令阅读一些该驱动程式的私家函数 (private functions) 和怪□的资料∶

perldoc DBD::mSQL

常见问题 (FAQ) POD 文件中也包含常见问题。要阅读的话请输入∶

perldoc DBI::FAQ

对不是永久或不能方便地连接上互联网的人来说这比较方便∶

POD 的一般资料 有关 POD 如何撰写 POD,及一般来说的 POD 哲学,可籍此阅读∶

perldoc perlpod

安装了 Tk 模组的用家可能会对一个名为 tkpod,使用 Tk 的 POD 阅读器有兴趣。它会把 POD 编排到一个方便及可阅读的形式∶

□谈、小道消息和观察∶ 在 DBI 的通信论坛中有不同人提出的一连串偶然的□谈。

“DBI□□perl5 资料库介面” 本文件由 Alligator Descartes 和 Tim Bunce 所写,关於 DBI 的结构。它在“The Perl Journal”第五期出版。它写得极之好。请买这本杂志。事实上,请每期都买。“The Perl Journal”的互联网网址是∶

“DBperl” 这文章在一九九六年十一月的“Dr. Dobbs Journal”发表,内容关於DBperl。

“The Perl5 Database Interface” 这是一本由 Alligator Descartes 写,由 O'Reilly and Associates 出版的书。

通信论坛 Ted Lemon 总共管理三个 DBI 的通信论坛。它们都可在万维网上订阅或取消 订阅∶

这些可加入的论坛是∶

dbi-announce 这通信论坛只是作出宣布。如果你不能成功使用以上网址的表格,请循以下途径订阅这论坛∶

dbi-dev 这通信论坛目的是让开发人员讨论有关 DBI 介面、API 和驱动程式机制的意见和概念。只对开发人员或有兴趣的人有用。如果你不能成功使用以上网址的表格,请循以下途径订阅这论坛∶

dbi-users 这通信论坛是用作错误报告、问题讨论和一般问题。如果你不能成功使用以上网址的表格,请循下途径订阅这论坛∶

通信储存处 (Mailing List Archives)∶

编译错误或「测试失败」

如果发生讯息转储 (core dump),尝试使用 Devel::CoreStack 模组来产生讯息转储的堆叠追踪 (stack trace)。Devel::CoreStack 可在 CPAN 找到∶

把堆叠追踪、模组版本、perl 版本、测试个案、操作系统版本及任何其他适用的资料电邮到 dbi-users 通信论坛。寄出的资料越齐全,开发人员越快解决问题。如果你不告诉我们,不要期望得到答案。

视窗 95/NT 有没有 DBI 支援?

DBI 和 DBD::Oracle 的 Win32 版本已成为 DBI 的标准部分。因此,比 DBI 0.81 高的版本应该会正常运作。透过 ODBC,你可以存取微软 Access 和 SQL-Server 资料库。在 DBI-0.79(及以後)有一个实验性质的 Win32::ODBC DBI 模拟层。它名为 DBI::W32ODBC。你需要使用 Win32::odbc 模组。

何谓 DBM?为何要用 DBI?

UNIX 原本是使用简单以档案为基础的「资料库」,即 dbm 系统。dbm 容许你在档案快速地存取资料。不过,它有数个严重的缺点。

档案封锁 (File Locking)

dbm 系统不容许特别全面的档案封锁能力,也没有修正同时写入资料库引起的问题的能力。

随意的资料结构

dbm 系统只容许单一固定的资料结构∶链-数值对 (key-value pair)。那数值可以是复杂的物件,如一个 C 的 struct,但链必须是独一无二的。这对 dbm 系统的用途造成很大限制。

不过,dbm 系统仍为使用简单资料及资源有限的用家提供了有用的功能,因为它快速、全面及经过极严谨的测试。存取 dbm 系统的模组现已经 AnyDBM_File 模组整合到 Perl 的核心散布中。

总括一句,对近乎是唯读的资料库或小型而简单的资料来说,dbm 是一个非常令人满意的解决方法。不过,对更强大和可增减 (scalable) 的资料集来说,用家最好使用 DBI。至於全面的交易封锁 (transactional locking),就更不用说了。□

DBI 是否支援<这项功能>?

根据所提出的功能是一个并不标准,而只为部分资料库所独有的假设,答案是否。

DBI 反映一个通用而可在大部分资料库使用的 API,而没有资料库独有的功能。

不过,如果驱动程式的作者有兴趣,他们可以籍 DBI 介面所定义的 func method 来加上资料库独有的功能。命令稿的开发人员要注意籍 func methods 提供的功能一般不能在不同资料库间移植。

对 CGI 来说,dbi 有没有用?

一个字∶有!DBI 对 CGI 程式设计非常有用!事实上,CGI 是 DBI 最重要的用途之一。

DBI 让 CGI 程式设计师设计功能强大的互联网前端资料库给他们的用家,从而提供大量按次序排列的资料。DBI 也容许在网站的资料库伺服器超过负荷时,管理人员在无须更改 CGI 命令稿的情况下将之升级。

我如何加快 CGI 与 DBD Oracle 的连接速度?

Apache httpd 管理一组子 httpd (httpd children) 来服务客户。籍著 Doug MacEachern 的 Apache mod_perl 模组,perl 翻译器已嵌入到子 httpd 中。CGI、DBI 和你喜欢的模组会在儿子诞生时载入。这些模组直到在磁碟上的版本被更改时才会再被载入。要知道更多有关 Apache 的资料,请看 Apache 计划的网站∶

如何使 DBI 和 CGI 持续连接?

籍著 Edmund Mergl 的 Apache::DBI 模组,每个子 httpd 会把资料库登入储存在杂凑 (hash) 中。如果你的应用程式只有一个资料库用家,每一个儿子都可开始连连。目前,儿子之间并不会分享资料库连接。Apache::DBI 可从 CPAN 下载∶

“我在指令行执行一个 perl 命令稿时,并无问题。不过,当我在 http 执行它时,它会失败!”何解?

基本上,这很有可能是因为从指令行执行命令稿的使用者已把环境变数设定好,以 DBD::Oracle 来说,即 $ORACLE_HOME, $ORACLE_SID 或 TWO_TASK。httpd 行程通常是以 nobody 的身份执行,即没有了设定好的环境。任何在这情况下尝试执行的手稿都会正确地失败。要解决这问题,在你的命令稿的开头用一个 BEGIN() 区块设定环境。这样便会解决问题。同样地,你要检查你的 httpd 错误纪录档以寻找线索,以及阅读“Idiot's Guide To Solving Perl / CGI Problems”和“Perl CGI Programming FAQ”以寻找更多资料。这问题大概不会和 DBI 有关。请两份文件都小心阅读!

使用 DBI 时,我能否进行多流处理 (multi-threading)?

目前不能。Perl 并不支援多流处理。不过,据估计,多流处理会成为 5.005 版的基本散布的一部分,即不久之後,DBI 可能会支援多流处理。要看一些使用多流 SELECT 句子的 Oracle OCI □例程式,请参阅∶

我如何用 DBI 呼叫内储程序 (stored procedure)?

假设你在目标资料库,例如一个 Oracle 资料库中建立了内储程序,你可使用 $dbh->do 来使程序立即执行。例如∶

$dbh->do( "BEGIN someProcedure END" );

在 DBI 中,我如何取回内储程序的返回值?

记著还要检查错误!

    $sth = $dbh->prepare( "BEGIN foo(:1, :2, :3); END;" );
    $sth->bind_param(1, $a);
    $sth->bind_param_inout(2, \$path, 2000);
    $sth->bind_param_inout(3, \$success, 2000);
    $sth->execute;

我可否用 DBI 来丢弃一个资料库?

对 DBI 来说,要适当地支援资料库的建立和丢弃太抽象了。例如,Oracle 根本不支援丢弃资料库!此外,在 Oracle 中,资料库伺服器基本上就是资料库,但在 mSQL,即使没有资料库,伺服器也能顺利地执行。这问题牵连太广了。正因如此,部分驱动程式透过私家 func 方法来建立和删除资料库。你要检查驱动程式的文件来了解它有没有支援这机制。

DBI 怎样处理 NULL 值?

DBI 被指定把 NULL 值当作 undef 值处理。NULL 可以 NULL 的数值来加入到资料库中,例如∶

    $rv = $dbh->do( "INSERT INTO table VALUES( NULL )" );
不过当查询时,NULL 要和 undef 比较。这是所有驱动程式都适用的标准。

这些 func 方法是做什麽的?

DBI 把 func 方法定义为资料库独有功能的进入点,例如建立和丢弃一个资料库。使用这些驱动程式独有方法十分简单,例如,要使用一个 createDatabase 方法输入一个引数 (argument) ,我们会写∶

    $rv = $dbh->func( 'argument', 'createDatabase' );
软件开发人员要注意 func 方法不能在不同资料库间移植。

商业支援及训练

Perl5 资料库介面是自由软体。它并没有任何担保 (warranty)。不过,有些机构提供了 DBI 的技术支援或培训计划。

PERL CLINIC : Perl Clinic 以合约形式为 Perl、DBI、DBD::Oracle 和 Oraperl 提供商业支援。这些支援是由 DBI 作者 Tim Bunce 工作的公司提供的。欲知详情,请看∶


Next Previous Contents