简介
Perl(Practical Extraction and Report Language)是一种功能强大而又非常简单易用的编程语言,在很多操作系统上都可以使用。Perl 是免费的。我们可以(以源代码或二进制的格式)下载这个语言,并可以免费地使用它。
Perl 日渐成为一种广受欢迎的语言。它包含了 C 编程语言的特性,以及 UNIX® 中的一些命令,例如 awk 和 sed。Perl 是一种解释语言,可以在单独的应用程序中使用,也可以与 Apache 一起来构建 Web 应用程序。
我们可以使用 Perl 快速操作来自文件或 RDBMS 的大型数据集。DBI 是在 Perl 脚本中连接 RDBMS 的标准,它是在 1994 年开始引入的。在 http://dbi.perl.org/ 站点上可以找到 DBI 驱动程序的源代码及其文档。
IBM 在 1992 年为 Perl 开发了 DB2 的驱动程序,并随着 DBI 规范的发展周期性地对其进行更新。这个驱动程序的最新版本(在撰写本文时)是 0.78。在 http://www.ibm.com/software/data/db2/perl/ 上可以找到主要的 DBD::DB2(这是 Perl 语言中采用的命名机制)驱动程序信息。
本文将展示如何编写简单的 Perl 程序来提取或操作 DB2 UDB 中存储的数据。我们将从一个简单的任务入手:从数据库中选择一行数据放入一个 Perl 程序中;接着逐步介绍一些高级主题,包括处理大对象和调用存储过程。
开始
图 1 展示了 Perl 环境如何与数据库环境进行交互:
图 1. Perl 环境
正如可以从这个图中看出的,Perl 程序使用了一个标准的 API 来与 DBI(Perl 的数据库接口模块)进行通信。Perl DBI 模块只能支持动态 SQL。它定义了一组方法、变量和约定来提供一个与实际使用的数据库独立的一致数据库接口。DBI 为 API 提供了一个一致的接口,它可以适用于程序员想使用的任何数据库。DBD::DB2 是一个 Perl 模块,当与 DBI 一起使用时,它就可以让 Perl 与 DB2 UDB 进行通信。
因此,为了运行访问 DB2 数据库的 Perl 脚本,需要在系统上安装以下组件:
Perl 语言环境
DBI 驱动程序(可以用于任何 RDBMS)
DBD::DB2 驱动程序
DB2 Runtime Client
C 编译器
DB2 数据库服务器的连接信息
在 http://www.ibm.com/software/db2/perl/ 的 Web 站点上可以看到所有的安装配置指南。
连接到 DB2 数据库上
为了让 Perl 程序访问 DB2 数据库,需要建立到数据库的连接。为了让 Perl 加载 DBI 模块,需要在 Perl DB2 应用程序中包含下面的内容:
use DBI;
当使用 DBI->connect 语句(语法如下)来创建一个数据库句柄 时,DBI 模块会自动加载 DBD::DB2 驱动程序。
清单 1. 创建数据库句柄
use DBI;
$dbh = DBI->connect (“dbi:DB2:dbalias", $UserId, $password);
其中:
$dbh | —— 表示 connect 语句所返回的数据库句柄 |
dbalias | —— 表示分类进 DB2 数据库目录中的 DB2 别名 |
$userID | —— 表示用来连接数据库的用户 ID |
$password | —— 表示这个用户 ID 的密码 |
清单 2 展示了一个简单的 Perl 程序,它建立到数据库 SAMPLE 的连接,并返回今天的日期。这个程序执行一条动态生成的 DB2 SQL 语句,从数据库中获取 CURRENT DATE。它使用 DBI -> bind_col 方法将数据库中的值传递到一个本地变量中,稍后我们就会讨论这个问题。
清单 2. 连接到数据库上并执行语句
#!/usr/local/bin/perl -w
use DBI;
use strict;
# Open a connection
my $dbh = DBI->connect("dbi:DB2:sample", “DB2ADMIN", “db2admin“, {RaiseError => 1});
# use VALUES to retrieve value from special register
my $stmt = "Values CURRENT DATE";
my $sth = $dbh->prepare($stmt);
$sth->execute();
# associate variables with output columns...
my $col1;
$sth->bind_col(1,\$col1);
while ($sth->fetch) { print "Today is: $col1\n"; }
$sth->finish();
$dbh->disconnect();
错误处理 —— SQLCODE 和 SQLSTATE
为了返回与某个 Perl DBI 数据库句柄或语句句柄相关的 SQLSTATE,可以调用 state 方法。例如,要返回与数据库句柄 $dbhandle 相关的 SQLSTATE ,可以在应用程序中使用下面的 Perl 语句:
my $sqlstate = $dbhandle->state;
为了返回与某个 Perl DBI 数据库句柄或语句句柄相关的 SQLCODE,可以调用 err 方法。例如,要返回与数据库句柄 $dbhandle 相关的 SQLCODE,可以在应用程序中使用下面的 Perl 语句:
my $sqlcode = $dbhandle->err;
errstr 方法返回与某个 Perl DBI 数据库句柄或语句句柄相关的 SQLCODE 的消息。我推荐使用这个方法,因为这个方法可以给出有关 SQL 语句失败的更多信息。
清单 3 中的例子展示了这个方法的用法:
清单 3. 返回错误消息的 errstr 方法
$dbh = DBI->connect("dbi:DB2:sample",“USERID",“password") or
die “Can't connect to sample database: $DBI::errstr";
$sth = $dbh->prepare(“SQL statement“) or die "Cannot prepare: " $dbh->errstr;
$sth->>execute() or die "Cannot execute: " $sth->errstr;
现在让我们进一步看一下第一个实验。它展示了一个 Perl 程序,这个程序使用作为参数传入的用户 ID 和密码来连接数据库 SAMPLE。当传递了有效的 ID 和密码时,它会返回一条消息说明连接成功了。下面是 lab1.pl 的代码:
清单 4. lab1.pl
#!/usr/local/bin/perl –w
use DBI;
$db2user = $ARGV[0];
$pasw = $ARGV[1];
# Open a connection
$dbh = DBI->connect("dbi:DB2:sample", $db2user, $pasw) or
“Can't connect to sample database: $DBI::errstr";
print "Connection is successful !!\n";
图 2 给出了使用有效身份验证和无效身份验证来执行这个程序的结果:
图 2. 执行 lab1.pl
查看原图(大图)
执行 SQL 语句
下面让我们来编写一个程序,在数据库 SAMPLE 中创建一个表 PT_ADDR_BOOK。要执行在编写应用程序时就已经知道的 SQL 语句,可以使用 $dbh->do 方法。这个方法的语法如下所示:
my $cnt = $dbh->do(SQL statement);
其中 $cnt 是这条 SQL 语句所影响的行数。
使用这个方法,我们的程序创建了一个 DB2 表,如清单 5 所示:
清单 5. 用来创建 DB2 表的程序
#!/usr/local/bin/perl -w
use DBI;
use DBD::DB2::Constants;
$dbh = DBI->connect("dbi:DB2:sample","","") or
die “Can't connect to sample database: $DBI::errstr";
$rcount = $dbh->do (“CREATE TABLE PT_addr_book(name char(30),
phone char(10))");
print “Returns: $rcount\n";
可以使用相同的 do 方法向 PT_addr_book 表中插入几行数据。请注意,所插入行的值在编写这个程序时都是已知的,因此可以硬编码在代码中。
清单 6. 使用 do 方法插入几行数据
#!/usr/local/bin/perl -w
use DBI;
use DBD::DB2::Constants;
$dbh = DBI->connect("dbi:DB2:sample","","") or
die "Can't connect to sample database: $DBI::errstr";
$rcount = $dbh-> do ("Insert into PT_ADDR_BOOK values
('Gregory Whales','9142712020'),
('Robert Moses', 2127652345')");
print "Returns: $rcount \n";
正如从这个例子中可以看到的,这条 SQL 语句会影响两行数据。通过在 DB2 CLP 中对这个表运行 SELECT 语句,可以确定有两行数据已经插入了这个表中。
清单 7. test_do_exs.pl
$perl test_do_exs.pl
Returns : 2
$db2 “select * from PT_ADDR_BOOK"
NAME PHONE
------------------------------ ----------
Gregory Whales 9142712020
Robert Moses