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
                                    <[email protected]>
                                    http://www.mbay.net/~mpeppler
    Oraperl     Oracle 6 & 7        Kevin Stock     DBD::Oracle
                                    <[email protected]>
    Ingperl     Ingres              Tim Bunce &     DBD::Ingres
                                    Ted Lemon
                                    <[email protected]>
    Interperl   Interbase           Buzz Moschetti  DBD::Interbase
                                    <[email protected]>
    Uniperl     Unify 5.0           Rick Wargo      None
                                    <[email protected]>
    Pgperl      Postgres            Igor Metz       DBD::Pg
                                    <[email protected]>
    Btreeperl   NDBM                John Conover    SDBM?
                                    <[email protected]>
    Ctreeperl   C-Tree              John Conover    None
                                    <[email protected]>
    Cisamperl   Informix C-ISAM     Mathias Koerber None
                                    <[email protected]>
    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