一、簡介
PERL應用程式資料庫由兩種方法,其一是利用本身所配置的DBM包,這個可以建立資料庫並對其進行操作,因此可以把DBM包以及其他類似的包看作是一個資料庫的擴充。另一個就是利用DBI包或者類似的包建立與其他關係型資料庫的串連,顯然,我們通常需要利用後者。
資料庫介面(DBI)是由TIM BUNCE(Tim.Bunce@ig.co.uk)所書寫,DBI是專門為PERL所書寫。你可以在
http://www.hermetica.com/technologia/DBI/ 尋找到相應的資訊。
最初,DBI只是由Tim Bunce開發的一個介面包,後來,他開發了DBD::Oracle包用於處理與Oracle的介面。然後,就有了一系列的DBD::Modules的包用於處理與其他類型的資料庫的介面。同樣,你可以在:
http://www.hermetica.com/technologia/DBI/取得詳細的資訊。現在可以得到的包有如下:
DBD-Oracle-0.29.tar.gz : Oracle 資料庫
DBD-Informix-0.20pl0.tar.gz : Informix 資料庫
DBD-QBase-0.03.tar.gz : Quickbase
DBD-mSQL-0.60pl9.tar.gz : mSQL-based 資料庫
DBI-0.67.tar.gz : DBI 介面
另外還有ODBC的驅動,從而可以載WINDOWS系統下驅動如ACCESS之類的資料庫系統。(當然,PERL FOR WIN32中也有WIN32::ODBC的包用於處理ODBC相容的驅動程式)
當取回DBI的驅動程式套件之後,先不急安裝,首先,測試PERL5是否安裝,這一點很重要,然後:
如果PERL5已經安裝: perl Makefile.PL
如果沒有安裝:perl Makefile.PL PERL_SRC=/path/to/perl/source/dir
然後:
make
make install完成安裝
你可以在系統下執行指令$ PERL_DL_DEBUG=255 perl -e 'use DBI;'
然後可以得到大致如此的結果:
DynaLoader.pm loaded (/usr/local/lib/perl5/i486-linux/5.003 /usr/local/lib/perl5
/usr/local/lib/perl5/site_perl/i486-linux /usr/local/lib/perl5/site_perl .
/usr/local/lib /usr/local/lib /lib /usr/lib)
DynaLoader::bootstrap for DBI (auto/DBI/DBI.so)
這樣說明你的DBI包已經安裝成功了。
DBI和DBD包啟動並執行模式如下:
(圖:DBI、DBD的工作模式)
讓我們看看串連資料發生的典型的過程:
1、載入DBI驅動程式
2、使用DBD串連相應的資料庫
3、開啟含有SQL指令的遊標
4、取回資料集
5、關閉遊標
6、關閉資料庫連接
7、退出
我們使用DBI之前首先需要聲明:
#!/usr/bin/perl -w
use DBI;
我們有兩種方法可以建立PERL與資料庫之間的串連:
#!/usr/bin/perl -w
use DBI;
#建立與資料庫的串連,第4個參數標明資料庫類型
$dbh = DBI->connect( 'connection_string', 'username', 'password', 'mSQL' );
if ( !defined $dbh ) {
die "Cannot do /$dbh->connect: $DBI::errstr/n";
}
通過這種方法,返回一個資料庫控制代碼。這是一種常用的用法,另外一種方法返回“驅動程式控制代碼”:
#!/usr/bin/perl -w
use DBI;
$drh = DBI->install_driver( 'mSQL' );
if ( !defined $drh ) {
die "Cannot load driver: $!/n";
}
這種方法多用來檢查是否系統中是否存在某種驅動程式。
在使用中,有三種控制代碼將要在程式設計中涉及到:驅動程式控制代碼(Driver Handle)、資料庫控制代碼(DataBase Handle)、語句控制代碼(Statement Handle),它們之間的關係可以用來表示:
(圖:驅動程式控制代碼、資料控制代碼和語句控制代碼的工作關係)
以下是一些利用DBI處理資料庫的曆程:
1、開啟串連(資料庫)已經關閉
#!/usr/bin/perl -w
#
# (c)1996 Alligator Descartes
#
# inout.pl: Connects and disconnects from a specified database
use DBI;
if ( $#ARGV < 0 ) {
die "Usage: inout.pl /n";
}
# Create new database handle. If we can't connect, die()
$dbh = DBI->connect( '', $ARGV[0], '', $ARGV[1] );
if ( !defined $dbh ) {
die "Cannot connect to mSQL server: $DBI::errstr/n";
}
# Disconnect from the database
$dbh->disconnect;
exit;
二、DBI與DBD::mysql
DBI是一個許多資料庫通用的介面,這意味著你可以寫出一個可以工作於許多不同的資料庫的指令碼。為此,你需要一個為每中資料庫類型定義的DATABASE DRIVER(DBD),對於MySQL來說,這個驅動程式叫DBD::mysql。你可以參考DBIs web page以獲得更多的資訊。為了獲得在Perl5中的關於物件導向編程的概念,請參考the perl OOP page
三、DBI介面
通用DBI方法
connect
建立與一個資料庫伺服器的串連
prepare
擷取準備執行的SQL語句
do
準備並執行一個SQL語句
disconnect
斷開與一個資料庫伺服器的串連
quote
被插入引用字串(塊)
execute
執行預存程序
fetchrow_array
取出下一行到一個數組之中
fetchrow_arrayref
取出下一行到數組中,返回數組的引用
fetchrow_hashref
取出下一行到雜湊表,返回其引用
fetchall_arrayref
取出所有的資料到一個數組,返回其引用。
finish
結束語句、釋放系統資源
rows
返回作用的行的數目
data_sources
返回本機中可用的資料庫的數組。
ChopBlanks
去除空格
NUM_OF_PARAMS
預存程序中預留位置的數目
NULLABLE
哪一個行允許Null。
MySQL 的特殊方法
insertid
最後自動遞增的值
is_blob
為BLOB的行
is_key
為鍵的行
is_num
為數位行
is_pri_key
為主鍵的行
is_not_null
不能為NULL的行
length
理論上最大的列的數目
max_length
物理上最大的列的數目
NAME
列名
NUM_OF_FIELDS
返回的欄位的數目
table
返回的集中的表的名稱
type
行的類型
_CreateDB
建立一個資料庫
_DropDB
刪除一個資料庫
connect:
使用connect方法建立一個到資料來源的串連。$data_source應該以DBI:driver_name:開始,例如:
$dbh = DBI->connect("DBI:mysql:$database", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user, $password);
如果使用者名稱或者是口令沒有定義的話,那麼DBI將使用DBI_USER,DBI_PASS環境變數分別作為其值。如果你沒有定義主機的話,那麼預設的是“localhost”,如果你沒有定義連接埠號碼的話,以預設的mysql的連接埠號碼(3306)作為連接埠號碼。
prepare:
通過資料庫引擎預備SQL語句並且返回一個語句控制代碼($sth)用於參與execute方法,例如:
$sth = $dbh->prepare($statement) or die "Can't prepare $statement: $dbh->errstr/n";
do
do方法預備並執行一個SQL語句,返回作用的行的數目,這個方法通常用於非select的語句,同時一般不需要執行多次(例如:insert,delete等)。例如:
$rc = $dbh->do($statement) or die "Can't execute $statement: $dbh- >errstr/n";
disconnect
disconnect將斷開與資料庫的串連,通常在程式結束的時候使用。例如:
$rc = $dbh->disconnect;
quote
quote方法用於 "escape"任何在字串中的特定自負,並且加上引用標記。
$sql = $dbh->quote($string)
execute
該方法執行一個儲存的語句。對於非select的語句來說,它返回作用的行的數目,對於select語句來說,該方法僅僅是開始了在資料庫中查詢,你需要fetch_*方法來取回資料。
$rv = $sth->execute or die "can't execute the query: $sth->errstr;
fetchrow_array
這個方法取回下一行的資料,並且將其儲存在一個數組之中。例如:
while(@row = $sth->fetchrow_array) { print qw($row[0]/t$row[1]/t$row[2]/n); }
fetchrow_arrayref
這個方法取回下一行的資料,並將其返回在一個對數組的引用之中。例如:
while($row_ref = $sth->fetchrow_arrayref) { print qw($row_ref->[0]/t$row_ref->[1]/t$row_ref->[2]/n); }
fetchrow_hashref
這個方法取回一行資料,並且返回一個到包含了欄位名/值的雜湊表的引用。這個方法不如使用一個數組引用的方法有效率。例如:
while($hash_ref = $sth->fetchrow_hashref) { print qw($hash_ref->{firstname}/t$hash_ref->{lastname}/t/ $hash_ref- > title}/n); }
fetchall_arrayref
這個方法被用來從一個SQL語句的執行結果中取回所有的資料(行)。它返回一個數組的引用,你可以通過一個迴圈來列印/顯示這些資料。
my $table = $sth->fetchall_arrayref or die "$sth->errstr/n"; my($i, $j); for $i ( 0 .. $#{$table} ) { for $j ( 0 .. $#{$table->[$i]} ) { print "$table->[$i][$j]/t"; } print "/n"; }
finish
指示沒有更多的資料可以被取出,你可以通過這個方法釋放語句控制代碼,並且釋放系統資源。例如:
$rc = $sth->finish;
rows
返回在(updated,delete等)操作中作用的行的數目。這通常被用在do()或者非select的execute()語句之後。例如:
$rv = $sth->rows;
NULLABLE
返回一個數組的引用,TRUE分別表示這個列可以允許NULL。
$null_possible = $sth->{NULLABLE};
NUM_OF_FIELDS
通過SELECT或者LISTFILEDS語句返回的列的數目。如果數目為0表示一個非SELECT語句的執行,例如,INSERT,DELETE或者UPDATE等。
$nr_of_fields = $sth->{NUM_OF_FIELDS};
data_sources
這個方法返回在localhost中的mysql服務中可用的資料庫的數組。
@dbs = DBI->data_sources("mysql");
ChopBlanks
這個方法決定了返回的行中是否去除空格。
$sth->{'ChopBlanks') =1;
insertid
如果你使用了mysql的自動增值的特性,那麼最新的自動增值將被儲存。例如:
$new_id = $sth->{insertid};
is_blob
返回一個數組的引用,TRUE分別表示所指示的列是BLOB。
$keys = $sth->{is_blob};
is_key
返回一個數組的引用,TRUE分別表示所指示的列是KEY。
$keys = $sth->{is_key};
is_num
返回一個數組的引用,TRUE分別表示所指示的列包含了數字。
$nums = $sth->{is_num};
is_pri_key
返回一個數組的引用,TRUE分別表示所指示的列是一個主鍵。
$pri_keys = $sth->{is_pri_key};
is_not_null
返回一個數組的引用,FALSE表示這個列可以包含NULL,而你最好使用DBI標準中的NULLABLE屬性。
$not_nulls = $sth->{is_not_null};
max_length、length
返回一個指示最大列的尺寸的數組的引用。最大長度是指在結果的表中的最大數值,LENGTH給出了理論上的最大值。
$max_lengts = $sth->{max_length}; $lengts = $sth->{length};
NAME
返回一個列名稱的數組的引用。
$names = $sth->{NAME};
table
返回了表名稱的數組的引用。
$tables = $sth->{table};
中文
$dbh->do("SET character_set_client='gbk'");
$dbh->do("SET character_set_connection='gbk'");
$dbh->do("SET character_set_results='gbk'");