perl 连接db2_使用DB2通用数据库进行Perl编程

本文详细介绍如何使用Perl编程语言连接并操作DB2数据库,包括执行SQL语句、调用存储过程及处理大对象数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

perl 连接db2

Perl(实用的提取和报告语言)是一种功能强大且易于使用的编程语言,可用于许多操作系统。 Perl是免费的。 您可以下载语言(以源代码或二进制形式)并使用它,而无需支付许可费用。

Perl是越来越受欢迎的选择。 它包含C编程语言的各个方面以及UNIX®命令(例如awksed 。 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环境

从图中可以看到,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
执行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程序,请按照下列步骤操作:

  1. 准备SELECT语句。
  2. 执行准备好的语句。
  3. 使用$ sth-> bind_col方法将列(或函数)的值与本地Perl变量关联
  4. 使用$ 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_arrayfetchrow_arrayref来检索LOB数据。 使用DBI,您可以使用LongReadLen连接属性设置每次提取时要检索的最大字节数。 LOB列的默认值为32,700字节。 为此,我们需要执行以下步骤:

  1. 编写SQL语句以从MAP表中选择图片。
  2. 准备SQL语句。
  3. 为将存储检索到的图像的文件分配一个名称。
  4. 打开该文件。
  5. 执行SQL语句。
  6. 使用提取方法将结果提取到文件中。

以下代码演示了如何从数据库中检索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技能。


翻译自: https://www.ibm.com/developerworks/data/library/techarticle/dm-0512greenstein/index.html

perl 连接db2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值