perl 连接db2
Perl(实用的提取和报告语言)是一种功能强大且易于使用的编程语言,可用于许多操作系统。 Perl是免费的。 您可以下载语言(以源代码或二进制形式)并使用它,而无需支付许可费用。
Perl是越来越受欢迎的选择。 它包含C编程语言的各个方面以及UNIX®命令(例如awk
和sed
。 Perl是一种解释性语言,可以在独立应用程序中使用,也可以与Apache一起使用来构建Web应用程序。
您可以使用Perl快速处理来自文件或RDBMS的大量数据。 DBI是将Perl脚本连接到RDBMS的标准,它于1994年引入。您可以在http://dbi.perl.org/上找到DBI驱动程序源及其文档。
IBM在1995年为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运行时客户端
- C编译器
- DB2数据库服务器的连接信息
您可以在http://www.ibm.com/software/db2/perl/网站上找到所有安装和配置指示信息。
连接到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:代表用户标识的密码
清单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;
现在,让我们一起通过实验#1。 它演示了一个Perl程序,该程序以用户ID和密码作为参数传递到数据库SAMPLE,并带有用户ID和密码。 传递了有效的用户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语句影响的行数。
使用此方法,清单5显示了我们创建DB2表的程序:
清单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 2127652345
2 record(s) selected.
请使用下载中的实验2中的练习来编写和执行一个简单的Perl程序,以更新PR_ADDR_BOOK表。
INSERT,UPDATE和DELETE语句-无占位符
执行在编写应用程序时未知SQL语句(动态SQL)的执行需要另一种技术,并且可以使用$dbh->prepare
方法来完成。 动态SQL的特点是能够在程序执行期间更改列,表和谓词。 需要为UDB优化器准备执行动态SQL,以便为该语句创建访问计划。 如果动态SQL没有参数标记(占位符),则可以在该步骤之后立即执行。 清单8显示了$dbh->prepare
和$sth->execute
方法的语法,这些方法将不带占位符SQL语句嵌入到Perl程序中:
清单8.动态SQL准备和执行
$stmt = "SQL Statement without placeholder";
$sth = $dbh->prepare($stmt);
$sth->execute();
请注意, $dbh->prepare
方法的结果是SQL语句句柄。
清单9中的Perl程序演示了如何使用以下方法将一行插入PT_ADDR_BOOK表:
清单9.插入一行
#!/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";
$stmt = "INSERT INTO PT_addr_book values ('JOHN SMITH','9145556677')";
$sth = $dbh->prepare($stmt);
$sth->execute();
print "We inserted row into addr_book\n";
$sth->finish();
带参数标记SQL语句
现在让我们看看如何执行在编写应用程序时未知的,具有参数标记或占位符SQL语句。 也就是真正的动态SQL语句。 请注意,建议使用此类SQL语句,这样可以提高性能和安全性。 从性能的角度来看,动态SQL语句可以准备一次并执行多次,从而重用相同的数据库访问计划。 从安全角度来看,占位符可确保仅将单个值绑定到该语句中,从而防止SQL语句错误。
为了使PERL程序将动态SQL语句转换为可执行形式,您需要首先使用prepare方法,然后使用bind_param方法绑定参数。 只有这样,您才能执行此语句。 要绑定每个参数,您需要指定参数标记的数量和包含参数标记值的本地Perl变量。 清单10显示了允许Perl程序执行动态SQL语句的方法的语法:
清单10.动态SQL的方法
$stmt = "SQL Statement with parameter marker";
$sth = $dbh->prepare($stmt);
$sth->bind_param(1,$parm,\% attr);
$sth->execute();
清单11演示了对表PT_ADDR_BOOK的INSERT。 现在,插入的列的值不会在SQL语句中进行硬编码,而是通过使用$ sth-> bind_param方法绑定到该语句的参数标记动态传递到该语句中。 只有在那之后,语句才被执行。
清单11.插入到表PT_ADDR_BOOK中
#!/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";
$name ="STEVE BROWN";
$phone = "7184358769";
$stmt = "INSERT INTO PT_addr_book values (?,?)";
$sth = $dbh->prepare($stmt);
$sth->bind_param(1,$name);
$sth->bind_param(2,$phone);
$sth->execute();
print "We inserted row into addr_book\n";
$sth->finish();
从数据库检索数据-单结果
为了从数据库获取值到Perl程序,请按照下列步骤操作:
- 准备SELECT语句。
- 执行准备好的语句。
- 使用$ sth-> bind_col方法将列(或函数)的值与本地Perl变量关联 。
- 使用$ sth-> fetch方法将值提取到局部变量中。
以下伪代码演示了如何从数据库中检索单个值:
清单12.从数据库检索单个值
$stmt = "SQL SELECT Statement to be executed";
$sth = $dbh->prepare($stmt);
$sth->execute();
$result = $sth->bind_col(col, \variable [, \%attr ]);
while ($sth->fetch){
process result of the fetch;
}
下一个示例显示如何从EMPLOYEE表中检索薪水列的合计函数max
的值:
清单13.检索聚合函数的值
#!/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";
$stmt = "SELECT max(salary) from EMPLOYEE";
$sth = $dbh->prepare($stmt);
$sth->execute();
#associate variable with output columns...
$sth->bind_col(1,\$max_sal);
while ($sth->fetch) {
print "The biggest salary is: $max_sal\n";
}
这是执行此Perl程序的结果:
清单14.汇总值结果
$perl test_return_value.pl
The biggest salary is: 52750.00
从数据库检索数据-多个结果
将结果集(或多个结果)从数据库返回到Perl程序的技术几乎相同。 准备并执行返回多个结果SQL语句,并将返回的值(列)绑定到局部变量后,您将需要使用$sth->fetch
方法来检索这些值。 为了演示其工作原理,让我们从PT_ADDR_BOOK表中检索phone和name列的值。 清单15显示了$sth_fetch
方法的迭代使用:
清单15.插入到表PT_ADDR_BOOK中
$stmt = "SELECT name, phone from PT_ADDR_BOOK";
$sth = $dbh->prepare($stmt);
$sth->execute();
#associate variables with output columns...
$sth->bind_col(1,\$name);
$sth->bind_col(2,\$phone);
print "NAME PHONE \n";
print "------------------------- -----------\n";
while ($sth->fetch) {
print $name ;
print $phone; print "\n"; }
print "DONE \n";
$sth->finish();
这是执行该代码的结果:
清单16.插入到表PT_ADDR_BOOK中
C:\Dev_POT\PERL\Labs>perl multi.pl
NAME PHONE
------------------------- -----------
JOHN SMITH 9145556677
STEVE BROWN 7184358769
DONE
您还可以使用方法$sth->fetchrow
从结果集中检索值。 $sth ->fetch
方法将每个值作为单独的实体返回,而$sth ->fetchrow()
方法将一行作为数组返回,每列一个值。
可以使用fetchrow
方法编写相同的Perl程序,如下所示:
清单17.插入到表PT_ADDR_BOOK中
$stmt = "SELECT name, phone from PT_ADDR_BOOK";
$sth = $dbh->prepare($stmt);
$sth->execute();
print "NAME PHONE \n";
print "------------------------- -----------\n";
while (($name, $phone) = $sth->fetchrow())
{ print "$name $phone\n"; }
使用实验3中的练习来编写和执行一个Perl程序,该程序将创建一个DB2表,将值插入该表,并返回插入该表的行数。
调用存储过程
让我们创建一个多步骤场景,以了解如何从Perl程序中调用DB2存储过程。 首先,让我们创建一个简单的存储过程SP_GET_LOC,该存储过程从表ORG中返回给定部门的位置(步骤1)。
清单18.步骤1:创建存储过程
create procedure sp_get_loc (in deptin int, out loc varchar(13))
begin
select location into loc from org where deptnumb = deptin;
end @
请注意,此过程有一个输入和一个输出参数。 当我们从DB2命令行处理器(CLP)运行此过程时,它将返回部门10的位置NEW YORK。
清单19.步骤2:运行存储过程
$db2 "call sp_get_loc(10,?)"
Value of output parameters
--------------------------
Parameter Name : LOC
Parameter Value : New York
Return Status = 0
现在,让我们编写一个简单的Perl程序来调用存储过程SP_GET_LOC(步骤3,请参见清单20 )。 实际上,我们的动态SQL语句与从DB2 CLP命令发出的语句相同: SP_GET_LOC(?,?)
,但是我们使用参数标记代替传递硬编码的10(部门编号)。 这样,我们可以绑定ORG表中部门编号列的任何值。
编写完SQL语句后,所有其他步骤与带有参数标记的任何动态语句相同。 用$sth = $dbh->prepare
方法进行$sth = $dbh->prepare
。 部门编号绑定与输入参数$sth->bind_param
方法,使用绑定返回的位置作为输出参数$sth->bind_param_inout
方法,然后执行我们的动态SQL语句。
这是该程序:
清单20.步骤3:调用存储过程
#!/usr/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";
# Prepare our call statement
$sth = $dbh->prepare( "CALL SP_GET_LOC(?,?)" );
# Bind input parameter for department number
$sth->bind_param(1, 10);
# Bind output parameter - location
$sth->bind_param_inout (2, \$location, 13, db2_param_type=>SQL_PARAM_OUTPUT});
# Call the stored procedure
$sth->execute();
printf("Stored procedure returned location: %s\n", $location);
$sth->finish();
$dbh->disconnect;
如果执行此程序,我们将返回给定部门(在这种情况下为10)的LOCATION:
清单21.步骤4.执行调用DB2存储过程的Perl程序
$perl test_call_sp.pl
Stored Procedure returned location: New York
大对象操纵
与使用更复杂的语言(例如C或Java®)相比,在Perl中处理文件要容易得多。 我们将研究如何将文件中的数据直接填充到DB2大对象数据(LOB)列中。 插入大对象数据的最有效方法是将文件直接绑定到与DB2表中的LOB列类型相关联的输入参数。 Perl驱动程序将直接从文件读取并将数据传输到数据库服务器。 要将文件绑定到输入LOB参数,请在INSERT操作期间使用bind_param
方法时指定{db2_file => 1}参数属性。
在数据库中,模式POT下有表MAP。 该表具有列图片,其中包含声明为BLOB的区域的图像。 这是此表的DDL:
清单22. MAP表的DDL
create table POT.MAPS
( map_id INT,
map_name VARCHAR(13),
area INT ,
photo_format CHAR(3),
picture BLOB) ;
此外,我们还有文件pearcson.jpg,其中包含皮尔逊机场的地图:
图3.示例图

现在,让我们编写一个程序,该程序将在表POT.MAP中插入一行,其中包括JPG文件中的图像到PICTURE列中。 首先,我们将使用五个参数标记组成一个动态SQL语句。 然后,我们准备该声明。 在将参数绑定到prepared语句之前,我们需要指定包含要插入图像的文件的名称,并将其分配给本地Perl变量( $picture_file
)。 现在,我们可以将所有参数绑定到需要插入MAP表中的值。 请注意,我们为最后一个参数指定属性db2_file =>1
。 最后一步是执行INSERT语句。 这是该程序的代码:
清单23.插入一个LOB
#!/usr/bin/perl -w
use DBI;
use DBD::DB2::Constants;
%conattr = ( AutoCommit => 1,
# Turn Autocommit On
db2_info_applname => 'Maps Module', );
# Identify this appl
$dbh = DBI->connect("dbi:DB2:sample","", "",\%conattr) or die "$DBI::errstr";
$dbh->do("SET CURRENT SCHEMA POT");
$sql = "INSERT INTO MAPS(map_id, map_name, area, photo_format, picture)
VALUES(?,?,?,?,?)";
$sth = $dbh->prepare($sql);
$picture_file = "pearson.jpg"; # File containing our picture
$sth->bind_param(1, 100); # map_id
$sth->bind_param(2, "Pearson airport"); # map_name
$sth->bind_param(3, 416); # area
$sth->bind_param(4, "JPG"); # photo_format
$sth->bind_param(5, $picture_file, {db2_file => 1});
$rows_affected = $sth->execute();
printf("%d rows affected", $rows_affected);
$sth->finish();
$dbh->disconnect;
从数据库读取LOB
您可以使用标准提取方法(例如fetchrow_array
或fetchrow_arrayref
来检索LOB数据。 使用DBI,您可以使用LongReadLen
连接属性设置每次提取时要检索的最大字节数。 LOB列的默认值为32,700字节。 为此,我们需要执行以下步骤:
- 编写SQL语句以从MAP表中选择图片。
- 准备SQL语句。
- 为将存储检索到的图像的文件分配一个名称。
- 打开该文件。
- 执行SQL语句。
- 使用提取方法将结果提取到文件中。
以下代码演示了如何从数据库中检索LOB:
清单24.将INSERT插入表PT_ADDR_BOOK
#!/usr/bin/perl
use DBI;
use DBD::DB2::Constants;
%conattr =
(
AutoCommit => 1,
# Turn Autocommit On
db2_info_applname => 'Maps Module',
# Identify this appl
LongReadLen => 80000
# Don't retrieve LOBs
);
# Connect to our database
$dbh = DBI->connect("dbi:DB2:sample","", "",\%conattr) or
die "$DBI::errstr";
# Set the current schema to 'POT'
$dbh->do("SET CURRENT SCHEMA POT");
$sql = "SELECT picture FROM maps WHERE map_name ='Pearson airport'";
# Prepare the statement
$sth = $dbh->prepare($sql);
# Open output file
$out_file = "mypic.jpg";
open(OUTPUT, ">$out_file") or die "Cannot open $out_file because $!";
binmode OUTPUT;
$sth->execute;
@row = $sth->fetchrow;
print OUTPUT $row[0];
@row = "";
close(OUTPUT);
print "Picture in the file $out_file\n";
$sth->finish();
$dbh->disconnect;
运行此程序后,图像将放置在mypic.jpg文件中。
清单25.将INSERT插入表PT_ADDR_BOOK
$perl test_lobread.pl
Picture in the file mypic.jpg
请使用实验4中的练习来编写和执行一个Perl程序,该程序将从表中将二进制大对象检索到文件中。
结论
本文是为具有关系数据库经验的Perl程序员编写的,他们想学习如何编写访问DB2数据库的Perl程序。 在本文的过程中,您学习了如何连接到数据库,以及如何通过INSERT,UPDATE和DELETE语句操作数据库内容。 您还学习了如何从数据库检索数据,以及其他更高级的主题,包括调用存储过程和操作大型数据对象(LOB和BLOB)。 现在,您应该准备自己动手使用新的Perl DB2技能。
perl 连接db2