加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl DBI实例讲解

发布时间:2020-12-15 23:48:51 所属栏目:大数据 来源:网络整理
导读:此文档的目的是给使用Perl DBI模块访问数据库的开发人员提供一些实列。也为了减轻Perl DBI邮件列表的负担。 通过此文档,我们将建立更加友好的DBI程序来访问Oracle数据库。我们将从DBI基础知识开始,然后介绍一些关于提高性能跟稳定性的概念。 基础知识: 我

此文档的目的是给使用Perl DBI模块访问数据库的开发人员提供一些实列。也为了减轻Perl DBI邮件列表的负担。
通过此文档,我们将建立更加友好的DBI程序来访问Oracle数据库。我们将从DBI基础知识开始,然后介绍一些关于提高性能跟稳定性的概念。

基础知识:

我们要做的第一件事情是安装DBI模块。这在 DBI INSTALL 文档中有介绍。接着我们需要安装数据库驱动,或者称为DBD。其安装简介也在每个

DBD的包中有介绍。如大多数Perl模块一样,安装DBI/DBD是很容易的:
localhost:/opt/src/perl_modules/DBI-1.13$ perl Makefile.PL && make && make test && make install
装完DBI 跟 DBD,你可以这样得到更多的信息:
localhost:~$ perldoc DBI

连接数据库
连接不同的数据库需要不同的方法。为得到详尽的信息,请阅读来在DBD的说明文档。 下面的例子适用于连接Oracle:

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',????????????????????????'jeffrey',????????????????????????'jeffspassword',??????????????????????);

?????????????????????
?????????????????????
上面的连接字符串(DSN)有三个参数:数据源,用户名和密码。DSN(数据源名称) 形式是这样的:dbi:驱动名称:实列 。但是我们怎么知道
连接是成功还是失败了呢?首先,如果connect方法连接成功,将返回一个true,否则返回false。其次,DBI将在包变量$DBI::errstr设置
一个错误消息串。

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',??????????????????????)?||?die?"Database?connection?not?made:?$DBI::errstr";
$dbh->disconnect();

使用disconnect()方法将避免出现“Database handle destroyed without explicit disconnect”这样的错误。

选项
connect()方法可以带一个哈希选项。常用的哈希选项包括:AutoCommit,当它为true时,事务处理将被自动提交。RaiseError,它在DBI遇到
错误时调用croak $DBI::errstr。PrintError,它将调用DBI的warn $DBI::errstr。

在这个程序中,我们想使用事务处理,因此我们关闭AutoCommit,开启RaiseError,PrintError用其默认设置。?

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',????????????????????????{
??????????????????????????RaiseError?=>?1,??????????????????????????AutoCommit?=>?0
????????????????????????}
??????????????????????)?||?die?"Database?connection?not?made:?$DBI::errstr";
$dbh->disconnect();


注意的是,对于不支持事务处理的数据库而言,设置AutoCommit为false将导致严重错误。

发出SQL
现在我们打算在数据库上作些有用的事。有两种得到数据库SQL声明的方法。对于查询,将发挥行记录,比如SELECT,我们将使用prepare 方法
对于其他查询,比如CREATE? 跟 DELETE,我们将使用 do 方法。让我们先来看一下后者,等一下下再看前一种情况。

这个程序将在数据库中建立一个雇员表 :

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',??????????????????????????AutoCommit?=>?0
????????????????????????}
??????????????????????)?||?die?"Database?connection?not?made:?$DBI::errstr";
my?$sql?=?qq{?CREATE?TABLE?employees?(?id?INTEGER?NOT?NULL,?
???????????????????????????????????????name?VARCHAR2(128),?
???????????????????????????????????????title?VARCHAR2(128),?
???????????????????????????????????????phone?CHAR(8)?
?????????????????????????????????????)?};
$dbh->do(?$sql?);
$dbh->disconnect();

???
???
?
中级
我们已经看到了怎样连接数据库,怎样发现错误以及发出简单SQL声明了。现在让我们继续前进看看更有用的代码吧。

SELECT 声明:
SELECT大概是SQL中最常用使用的了。为了用SELECT声明,我们首先将prepare(准备)声明,然后execute(执行)它。下列代码中,
$sth 变量是声明句柄,我们将利用它来访问SELECT的结果。

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',??????????????????????????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方法绑定每个数据库行和对应的一个标量引用,然后当fetch方法被调用时,这些
变量将装载从数据库里取来的值。

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',??????????????????????????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声明,执行将非常快。

use?strict;
use?DBI?qw(:sql_types);
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',??????????????????????????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,?$_,?SQL_VARCHAR?);
??$sth->execute();
??my(?$id,?$phone?);
??$sth->bind_columns(?undef,?$phone?);
??while(?$sth->fetch()?)?{
????print?"$name,?$phonen";
??}
}
$sth->finish();
$dbh->disconnect();

高级:
??? 事务处理:
??? 截止到现在,我们还没有用事务处理来做任何事情。但是如果我们想发出UPDATE 或者? DELETE声明,我们将会使用事务处理。通过参考
DBI文档,用DBI执行健壮的事务处理的最好方法是使用eval{...} 块去捕获错误。然后使用commit() 或者 rollback()来结束事务处理。这
就是我们下面的代码清单所做的事情。

程序往数据库里装载四条记录。

use?strict;
use?DBI?qw(:sql_types);
my?$dbh?=?DBI->connect(?'dbi:Oracle:orcl',??????????????????????????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],?SQL_INTEGER?);
????$sth->bind_param(?2,?@$_->[1],?SQL_VARCHAR?);
????$sth->bind_param(?3,?@$_->[2],?SQL_VARCHAR?);
????$sth->bind_param(?4,?@$_->[3],?SQL_VARCHAR?);
????$sth->execute();
????$dbh->commit();
??};
??if(?$@?)?{
????warn?"Database?error:?$DBI::errstrn";
????$dbh->rollback();?#just?die?if?rollback?is?failing
??}
}
$sth->finish();
$dbh->disconnect();

? 调用Oracle存储过程:
? 通过DBI用户邮件列表,我通常被问及的一个问题是,怎么用DBD::Oracle调用存储过程。这里我给出复杂多变的例子。
?
这个程序用一个参数调用存储过程,没有返回值。我们假设这个不过不调用commit。注意程序中位置占位符的使用,同时也注意eval块的使用
:如果你的Oracle程序产生了列外,在你的Perl程序中将被“翻译”成die,错误信息将被保留在$@ 和 $DBI::errstr变量中。


use?strict;
use?DBI;
my?$dbh?=?DBI->connect(
????'dbi:Oracle:orcl',????'jeffrey',????'jeffspassword',????{
????????RaiseError?=>?1,????????AutoCommit?=>?0
????}
)?||?die?"Database?connection?not?made:?$DBI::errstr";
eval?{
????my?$func?=?$dbh->prepare(q{
????????BEGIN
????????????jwb_function(
????????????????parameter1_in?=>?:parameter1
????????????);
????????END;
????});
??
????$func->bind_param(":parameter1",?'Bunce');?#位置占位符时方便的
????$func->execute;
??
????$dbh->commit;
};
if(?$@?)?{
????warn?"Execution?of?stored?procedure?failed:?$DBI::errstrn";
????$dbh->rollback;
}
$dbh->disconnect;

下一个程序调用带返回值的存储过程,从一个函数中返回一个值,我们使用bind_param_inout来绑定占位符。当使用这种方法时,我们必须
通知DBD::Oracle模块返回值有多少字节。

use?strict;
use?DBI;
my?$dbh?=?DBI->connect(
????'dbi:Oracle:orcl',????????AutoCommit?=>?0
????}
)?||?die?"Database?connection?not?made:?$DBI::errstr";
my?$rv;?#holds?the?return?value?from?Oracle?stored?procedure
eval?{
????my?$func?=?$dbh->prepare(q{
????????BEGIN
????????????:rv?:=?jwb_function(
????????????????parameter1_in?=>?:parameter1
????????????);
????????END;
????});
??
????$func->bind_param(":parameter1",?'Bunce');
????$func->bind_param_inout(":rv",?$rv,?6);
????$func->execute;
??
????$dbh->commit;
};
if(?$@?)?{
????warn?"Execution?of?stored?procedure?failed:?$DBI::errstrn";
????$dbh->rollback;
}
print?"Execution?of?stored?procedure?returned?$rvn";
$dbh->disconnect;

备注:1.这些例子中的finish方法不是必需的。如果你是用声明句柄而不是你自己的程序来做,那么你应该调用finish方法。2.永远使用use strict句法。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读