http://hi.baidu.com/hexie007/item/c4e1e2cc5414f00a0ad93ad5
对于关系型数据库perl提供了DBI(Database Interface)module,设计思想类似于Java中的JDBC,利用对不同数据库定制的DBD(Database Driver)来实现程序的可移植性。当然,在获得移植性的便利下,会在性能上有所损失。
下面来对DBI的主要方法进行说明,掌握了主要的方法就可以实现“知道20%的知识就可以完成80%的工作”。DBI的使用很简单,需要做的是与相应的数据库进行连接,并发出相应的SQL指令就可以了。
数据库连接
use DBI;
$dbname = 'empdb';
$user = 'sriram';
$password = 'foobar';
$dbd = 'Oracle';
$dbh = DBI->connect($dbname, $user, $password, $dbd);
if(!$dbh){
print $DBI::errstr;
}
$dbd用来告诉DBI加载DBD::Oracle模块。所有的DBI语句在失败时返回undef。错误代码和错误信息可以从$DBI::err和$DBI::errstr中获得。
基本的SQL存取
$dbh->do("delete from emptable where status != 'active'");
print $DBI::errstr if DBI::err;
如 果同样的查询与志类似的查询执行多遍,那么系统会被迫对它一遍遍的语法分析。为避免这种负载,可以使用prepare来编译一个参数华的查询,并使用 execute来进行多遍执行。prepare方法将接收"?"表示的参数位置的查询:(和JDBC的Connect.prepareStatement ()的思想一致)
$sth = $dbh->prepare('insert into emptable (id, name) values (?, ?)');
你可以使用$sth来不停的执行这条语句,每次为响应的参数位置提供一个值数组。如下面的使用:
while(defined($line == <>)){
chomp($line);
#假设数据间用制表符分开
($id, $name) = split(/\t/, $line);
$sth->execute($id, $name);
die $DBI::errstr if DBI::err;
}
如果某个字段为空,可以用execute传递undef来表示空值。
select查询
下面这段例子演示了如何使用数据库操作中最常用的查询。
$cur = $dbh->prepare('select name from emptable where id < 100');
$cur->execute();
die $DBI::errstr if DBI::err;
while(($name) = $cur->fetchrow){
print "name: $name";
}
$cur->finish();
除了fetchrow外还有fetchrow_array;fetchrow_hashref;fetchall_arrayref;fetchall_hashref($key);等多种方法,具体细节参考perldoc DBI。
查询元数据
一旦一条语句准备好并予以执行,DBI将会以语句句柄属性的形式来保存下面的信息:
$DBI::rows
作用或返回的行数
$sth->{NUM_FIELDS}
由select语句返回的字段数
$sth->{NUM_PARAMS}
由任意查询返回的参数个数
执行完select语句可以得到以下元数据信息:
$sth->{NAME}
由查询所返回的列名称
$sth->{NULLABLE}
表示字段是否可以为空的布尔值
$sth->{TYPE}
字段类型
$sth->{PRECISION}
字段的浮点数精度
$sth->{SCALE}
字段长度
特殊函数
我们可以在数据库句柄上使用func方法来调用特定于驱动程序的函数,如
$ref = $dbh->func($table, '_ListFields');
上面一条语句调用了mySQL数据库提供的名为_ListFields的内部函数。但是,虽然可以利用该方法获得数据库的高级功能,但这不是一种可移植的方案。
DBI没有提供的功能
1、创建数据库
2、从数组中插入或创建
3、存储过程和触发器
4、统一的错误代码
*******************
Win32::ODBC
这个模块是ActiveWare移植perl到windows平台上处理数据库的模块,它与DBI的方法类似。它跟随ActivePerl一起安装的windows平台的。下面是一段实例代码:
use Win32::ODBC;
{
my $DSN="dbtest"; #需要设置系统级的DSN才可以调用该方法
my $table="test";
my $db=new Win32::ODBC($DSN);
if ($db) {
$db->Sql("SELECT * FROM $table");
while ($db->FetchRow()) {
my %result=$db->DataHash();
show(\%result);
}
$db->Close;
}else{
print "Failure:".Win32::ODBC::Error()."\n";
}
sub show{
my $ref=shift;
for (keys %$ref){
printf("%-5s : %s\n",$_,$ref->{$_});
}
}
}
这里的Sql语句等价于DBI中的do。ODBC没有语句句柄的概念;而是使用数据库句柄来获取查询结果。
1、Advanced Perl Programming, O'reilly, Sriram Srinivasan著
2、Perl 学习手札,http://sage.68ab.com/