Perl DBI 初级教程
目录? 1. 基本功能?? 2. 建立连接? 3. 选项?? 4. 下达?SQL?? 5. 进阶功能?? 6. SELECT语句? 7. 事务机制?? 8.参考资料?
本文是以?Perl?DBI?Examples?为蓝本,以及几个浅显易懂的例子,希望能够一步步地带领使用者学习?Perl?DBI?modules?存取数据库的方法。
读完本文之后,我们就能学到利用?DBI?建立一个完整的数据库程序。以下就先由?DBI?的基本功能开始,然后再逐步研究改善效率与可靠性技巧。
基本功能? DBI?-?Database?independent?interface?for?Perl。Perl?DBI?是?Perl?程序语言存取数据库时的标准应用程序接口?(API)。DBI?中定义了一组函数、变数和一致性的数据库接口,可满足与特定数据库无关的特性。
值得一提的,DBI?只是一个程序接口,将你的应用程序与一个以上的数据库驱动程序紧密地结合在一起,DBI?的架构主要只是提供标准的接口,目的是为了方便使用者下达一些简单的指令,就可以轻易地让那些驱动程序发挥作用?。
首先该做的事就是建构以及安装?DBI,详细的步骤可参考?配置中有说明。然后再来就是建构出所需的数据库驱动程序,或是参考?DBD。在每个?DBD?套件中都应该会有建构程序。与其他?Perl?模组相较之下,安装?DBI/DBD?步骤算是相当容易?:
?localhost:~/DBI-1.08$?perl?Makefile.PL?&&?make?? ????????&&?make?test?&&?make?install?? |
在?DBI?与?DBD?安装完成之后,您可以执行下列指令阅读更多的资讯:??
localhost:~$?perldoc?DBI?? |
??????????????????????
?
建立连接 每一种数据库都有不同的连接方式,若是想知道特殊用法,请务必阅读?DBD?所提供的说明文件。下面的例子是通过DBI::ODBC的基本方法。
use?strict;? use?DBI;?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ????????????????????????'testuser',? ????????????????????????'userpassword',? ??????????????????????);? |
?
???上述的?connect?函数用到了三个参数:?数据来源名称?(data?source?name,?DSN),?使用者名称和密码。其中?DSN?的格式为?dbi:DriverName:instance。不过我们要如何知道连接成不成功呢??首先可以查看?connect?的返回值,true?代表成功,false?就是代表失败。其次,当有错误发生时,DBI?会把错误讯息存放在?package?variable?$DBI::errstr?之中。?
use?strict;? use?DBI;?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";? $dbh->disconnect();? |
????? 结束数据库连接请使用?disconnect()?函数,正确地使用可避免错误讯息?"Database?handle?destroyed?without?explicit?disconnect"?的发生。?
选项? 在连接数据库时?connect()?这个方法可以接受?hash?型态的选项,常用的选项包括了:?AutoCommit,设为?true?表示数据库交易自动确认;?RaiseError,告诉?DBI?在错误发生时触发例外?croak?$DBI::errstr?而不只是仅返回错误代码;PrintError,让?DBI?以警告方式?warn?$DBI::errstr?返回错误讯息。?
在下一段程序中,是希望进行采交易处理的用法,设定成?AutoCommit?off,RaiseError?on,而让?PrintError?使用内定值?on。?
use?strict;? use?DBI;?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ????????????????????????{? ??????????????????????????RaiseError?=>?1,? ??????????????????????????AutoCommit?=>?0? ????????????????????????}? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";? $dbh->disconnect();? |
????? 有一点要特别注意,如果数据库本身不支持交易处理的功能时,设定?AutoCommit?off?会接收到错误发生的返回值。?
下达?SQL? 现在开始可以对我们的数据库做一些有意义的事了。下达至数据库的?SQL?述分成两类。一是查询指令,预期会有数据返回,例如?SELECT,这一类的指令我们会使用?prepare?方法。另一类的指令,如?CREATE?和?DELETE,我们会使用?do?方法。我们先看看后者如何使用。?
这一段程序示在数据库中建立一个员工数据表的方法。?
use?strict;? use?DBI;?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ??????????????????????????AutoCommit?=>?0? ????????????????????????}? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";?
my?$sql?=?qq{?CREATE?TABLE?employees?(?id?INTEGER?NOT?NULL,?? ???????????????????????????????????????name?VARCHAR(128),?? ???????????????????????????????????????title?VARCHAR(128),?? ???????????????????????????????????????phone?CHAR(10)?? ?????????????????????????????????????)?};? $dbh->do(?$sql?);? $dbh->commit();? $dbh->disconnect();? |
进阶功能? 我们已经学会了连接数据库,错误监测,以及下达简单的?SQL?的方法。是该学一些更有用的程序语法的时候了。?
SELECT语句 在?SQL?的述中,最常使用的指令莫过于?SELECT。为了使用?SELECT,我们应该先?prepare?这一段述,然后进行?execute?动作。在下面的程序片段中,我们都会使用?statement?handle?$sth?有存取?SELECT?的结果。?
use?strict;? use?DBI;? my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ????????????????????????'jeerrypassword',? ??????????????????????????AutoCommit?=>?0? ????????????????????????}? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";?
my?$sql?=?qq{?SELECT?*?FROM?employees?};? my?$sth?=?$dbh->prepare(?$sql?);? $sth->execute();?
$dbh->disconnect();?
|
????? 上述程序要求数据库为查询指令先准备好执行计画,之后再执行该查询指令。到目前为止还没有任何一笔记录返回。稍后我们会使用?bind_columns?的技术以取得数据库输出的记录。bind_columns?分别将每个输出栏位结到一个?scalar?reference。一旦呼叫到?fetch?时,这些?scalars?就会填入这数据库返回的值。?
use?strict;? use?DBI;?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ??????????????????????????AutoCommit?=>?0? ????????????????????????}? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";?
my?$sql?=?qq{?SELECT?id,?name,?title,?phone?FROM?employees?};? my?$sth?=?$dbh->prepare(?$sql?);? $sth->execute();?
my(?$id,?$name,?$title,?$phone?);? $sth->bind_columns(?undef,?$id,?$name,?$title,?$phone?);?
while(?$sth->fetch()?)?{? ??print?"$name,?$phonen";? }?
$sth->finish();? $dbh->disconnect();? |
?
倒是一个列出全公司通讯录的好方法,尤其是?WHERE?的使用让我们轻易地取出所有的数据输出。下面会利用到?bind_param?先将?SQL?述做一次?prepare,就能够高速地执行许多次。?
use?strict;? use?DBI;?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ??????????????????????????AutoCommit?=>?0? ????????????????????????}? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";?
my?@names?=?(?"Larry%",?"Tim%",?"Randal%",?"Doug%"?);?
my?$sql?=?qq{?SELECT?id,?phone?FROM?employees?WHERE?name?LIKE???};? my?$sth?=?$dbh->prepare(?$sql?);?
for(?@names?)?{? ??$sth->bind_param(?1,?$_);? ??$sth->execute();?
??my(?$id,?$phone?);? ??$sth->bind_columns(?undef,?$phone?);?
??while(?$sth->fetch()?)?{? ????print?"$name,?$phonen";? ??}? }?
$sth->finish();? $dbh->disconnect();?
|
????? 高级技巧?
事务机制? 到目前为止,我们的动作都还不需要使用到事务机制的功能,不过当下达?UPDATE?或是?DELETE?述时,我们就会希望使用到它了。根据?DBI?文件指出,如果想作一套稳固的事务机制,就应该配合?eval{… }?区块来拦截错误的发生,最后再使用?commit?或?rollback?来完成整个交易程序。这就是我们以下所要谈的内容。?
本程序示将四条数据插入数据库的方法。?
use?strict;? use?DBI?qw(:sql_types);?
my?$dbh?=?DBI->connect(?'dbi:ODBC:dbsample',? ??????????????????????????AutoCommit?=>?0? ????????????????????????}? ??????????????????????)? ??????????||?die?"Database?connection?not?made:?$DBI::errstr";?
my?@records?=?(? ????????????????[?0,?"Larry?Wall",??????"Perl?Author",??"555-0101"?],? ????????????????[?1,?"Tim?Bunce",???????"DBI?Author",???"555-0202"?],? ????????????????[?2,?"Randal?Schwartz",?"Guy?at?Large",?"555-0303"?],? ????????????????[?3,?"Doug?MacEachern",?"Apache?Man",???"555-0404"?]?? ??????????????);?
my?$sql?=?qq{?INSERT?INTO?employees?VALUES?(??,??,???)?};? my?$sth?=?$dbh->prepare(?$sql?);?
for(?@records?)?{? ??eval?{? ????$sth->bind_param(?1,?@$_->[0]);? ????$sth->bind_param(?2,?@$_->[1]);? ????$sth->bind_param(?3,?@$_->[2]);? ????$sth->bind_param(?4,?@$_->[3]);? ????$sth->execute();? ????$dbh->commit();? ??};?
??if(?$@?)?{? ????warn?"Database?error:?$DBI::errstrn";? ????$dbh->rollback();?#just?die?if?rollback?is?failing? ??}? }?
$sth->finish();? $dbh->disconnect();? |
注意事项? 1) 关于?finish?的呼叫在我们的例子并不是必要的。这个函数适用于?statement?handle?完成时所使用。? 2) 永远要加上?use?strict。?
参考资料
《OReilly.Programming.PerlDbi》
?
Per官方网站
http://www.perl.com/
?
Perl DBI官方网站
http://dbi.perl.org/
?
对DBI的一个简短介绍
http://www.perl.com/pub/1999/10/DBI.html??
?
对DBI的深入讨论帖子
http://search.cpan.org/~timb/DBI_AdvancedTalk/
?
一个PerlDBI的在线手册
http://search.cpan.org/~timb/DBI-1.617/DBI.pm
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|