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 规格定义了一组函数、变数和惯例,以提供一个一致而独立於实际所用资料库的介面。

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

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

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 模组的名单,所对应的 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 执行。

DBI 规格

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

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


DBI 规格的 PO 可用以下指令阅读
        $ perldoc DBI

使用结合到 DBD::Oracle 的 Oraperl 模拟层的人可用以下指令阅读如何用 Oraperl 介面编写程式∶
        $ perldoc Oraperl

DBD::mSQL 模组的用家可籍以下指令阅读一些该驱动程式的独家函数 (private functions) 和特异功能的资料∶
        $ perldoc DBD::mSQL

POD 文件中也包含常见问题。要阅读的话请输入∶
        $ perldoc DBI::FAQ

POD 的一般资料□有关 POD 如何撰写 POD,及整体的 POD 哲学,可籍以下指令阅读∶
        $ perldoc perlpod

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

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

用家可能参加的通信论坛为∶ The mailing lists that users may participate in are:

编译错误或「测试失败」

如果发生讯息转储 (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 模组。

对 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)?

要看一些使用多流 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 方法不能在不同资料库间移植。

商业支援及训练

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

11.3 测试 Perl 介面

请参阅 测试 Perl□Perl 介面一节


Next Previous Contents