首页 | 摘要显示 | 上一页 1 2 3 4 5 6 7 8 9 10 11 下一页

Developer Archives

学习Perl DBI -- 连接到数据库

    从data_sources函数知道了连接信息的格式后, 我们就可以连接了, 只要调用DBI的connect函数, 根据连接信息的格式, 可以自动区别数据库类型, 选择合适的数据库驱动进行连接. 一般写法如下:

my $dbh = DBI->connect("data source", "username", "password");
my $dbh = DBI->connect("data source", "username", "password", properties);

    connect函数如果连接失败会返回undef值, 因此很容易判断连接是否成功:

my $dbh = DBI->connect("dbi:Oracle:test8i","anysql", "anysql")
            || die("Cannot connect to database!\n");

my $dbh = DBI->connect("dbi:Oracle:test8i","anysql", "anysql");

if (!defined($dbh)
{
   ...
}

    连接属性常用的有两个: RaiseError和PrintError. RaiseError如果设为1时, 如果DBI调用遇到错误, 将引起程序退出, 设为0时遇到错误后将继续执行后续的代码. PrintError如果设为1时则遇到错误时打印错误信息, 设为0时则不打印错误信息. 那么如何在程序中获得错误信息呢? 可以通过DBI中的变量或连接对象的几函数来获得:

my $dbh = DBI->connect("dbi:Oracle:test8i","anysql", "anysql",
            {RaiseError=0,PrintError=0,});
......
my $errcode = $DBI::err;
my $errmsg  = $DBI::errstr;
my $errcode = $dbh->err();
my $errmsg  = $dbh->errstr();

    在程序中你可以随时更改PrintError和RaiseError的设定, 如下所示:

$dbh->{PrintError} = ...;
$dbh->{RaiseError} = ...;

    对于连接到Oracle这样的数据库时, 如果你不想再和数据库打交道了, 最好还是在代码中切断连接, 并在连接之前发一个commit或rollback(根据你的需要), 如下所示:

$dbh->commit();
$dbh->rollback();
$dbh->disconnect();

    这一部分其实还是比较复杂的, 在这儿就写得太简单了.

学习Perl DBI -- 处理查询语句

    在建立连接后, 就可以进行查询了. 可以用prepare函数来准备一个SQL语句, 获得一个Cursor的句柄(Handle)后就可以执行了, 如下所示:

my $sth = $dbh->prepare("select .....");

if (!defined($sth))
{
......
}

if ($sth->execute())
{
......
}

    在调用execute函数(如果成功返回True, 否则False)后, 接下来需要进行Fetch操作才能将查询的结果取出来, 取出记录有很多种方法:

my ($col1, $col2, ....);
while ( ($col1, $col2, ...) = $sth->fetchrow_array() )
{
.....
}

my @row;
while ( @row = $sth->fetchrow_array())
{
    print($row[0].",".$row[1].....);
}

my $rowref;
while ( $rowref = $sth->fetchrow_arrayref())
{
   print($rowref->[0].",".$rowref->[1].....);
}

my $rowref;
while ( $rowref = $sth->fetchrow_hashref())
{
   print($rowref->{col1}.",".$rowref->{col2}.....);
}

    在取完所有的记录后或你想要的记录后, 你可以调用一下finish方法:

$sth->finish();

    在这个例子中, 我们取记录都是一条一条地取的, 为了速度我们应当一批一批地读取记录, 这一点会在以后讲.

学习Perl DBI -- 绑定(Bind)变量

    给SQL语句动态地传入值的方法叫绑定(Bind), 在写数据库有关的角本时, 这是很重要的一点, 在Perl中你可以在SQL中写一个问号表示不确定的值, 不管是在SELECT还是在Insert/Update/Delete语句中, 都一样. 如下所示:

my $sth = $dbh->prepare( "select tname from tab
        where tname like ?");
......
my $sth = $dbh->prepare("Delete from test where col1=?");

    接下来在执行之前要传入真实的值和类型, bind_param就是用来传入值的, 第一个参数为问题的位置, 从1开始数; 第二个参数为变量的值; 第三个参数是可选的, 为参数的类型. 如下所示:

use strict:
use DBI;
USE DBI qw(:sql_types);

$sth->bind_param(1, "TEMP%");
$sth->bind_param(2, 2000);
$sth->bind_param(3, 2500, { TYPE=> SQL_VARCHAR });
$sth->bind_param(3, 2500, SQL_VARCHAR);

$sth->execute();

    在Perl中是不能按名字来绑定变量的, 即"COL1 = :p1 OR COL2 = :P1'这样的条件要写成"COL1 = ? OR COL2 = ?", 并且要传入二次参数. 在调用函数或存贮过程时, 经常会有转出类型的参数, 这时可以用bind_param_inout来实现, 例如有一个过程"p_test(v1 in number, v2 out number, v3 out number)", 要调用它的话, 要用如下写法:

my ($v1, $v2, $v3);
my $sth = $dbi->prepare("BEGIN P_TEST(?,?,?); END;");
$v1 = 123;
$sth->bind_param(1, $v1);
$sth->bind_param_inout(2, \$v2, 50);
$sth->bind_param_inout(2, \$v3, 50);
$sth->execute();

    常用的绑定类型有SQL_CHAR, SQL_NUMERIC, SQL_DECIMAL, SQL_INTEGER, SQL_SMALLINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE, SQL_DATE, SQL_TIME, SQL_TIMESTAMP, SQL_VARCHAR, SQL_LONGVARCHAR, SQL_BINARY, SQL_VARBINARY, SQL_LONGVARBINARY, SQL_BIGINT, SQL_TINYINT, SQL_BIT, SQL_WCHAR, SQL_WVARCHAR, SQL_WLONGVARCHAR. 除了上面的bind_param调用外, 也有更直接方便的方法来传入参数, 如:

my $sth = $dbh->prepare("select * from tab
   where tname like ?");
$sth->bind_param(1, "", SQL_VARCHAR);
$sth->execute("TEMP%");
......
$dbh->do("insert into test (col1) values (?)", 123);
......

    不管何种语言, 这一块的处理基本相同, Java中也是以问题来代表一个动态值的.

学习Perl DBI -- 处理返回记录(Fetch)

    在Perl中, 如果你的记录确保只有一条记录被返回, 则可以用以下的更简单的方法, 而不需要经过Prepare-Bind-Execute-Fetch四个阶段, 如下所示:

my ($iniext, $nxtext) = $dbh->selectrow_array (
   "SELECT INITITAL_EXTENT, NEXT_EXTENT FROM DBA_TABLESPACES
       WHERE TABLESPACE_NAME='USERS'");

my ($iniext, $nxtext) = $dbh->selectrow_array (
   "SELECT INITITAL_EXTENT, NEXT_EXTENT FROM DBA_TABLESPACES
       WHERE TABLESPACE_NAME=?", undef, "USERS");

my @row = $dbh->selectrow_array (
   "SELECT INITITAL_EXTENT, NEXT_EXTENT FROM DBA_TABLESPACES
       WHERE TABLESPACE_NAME=?", undef, "USERS");

my $rowref = $dbh->selectrow_arrayref (
   "SELECT INITITAL_EXTENT, NEXT_EXTENT FROM DBA_TABLESPACES
       WHERE TABLESPACE_NAME=?", undef, "USERS");

    在返回多行时, 前面说的一条一条地获取就会增加网络的来回访问, 使用一批一批(Batch)地Fetch将极大地提高性能. 可以使用selectall_arrayref或fetchall_arrayref来一次取得所有的记录放在本地的内存中, 如下所示:

$sth = $dbh->prepare(...);
$sth->execute();
my $rows = $sth->fetchall_arrayref();
foreach my $row (@$rows)
{
   my ($col1, $col2, ...) = @$row;
   ...
}

my $rows = $dbh->selectall_arrref(
  "select ts#, tablespace_name from v$tablespace");
......
  
my $rows = $dbh->selectall_arrref(
  "SELECT INDEX_NAME FROM USER_INDEXES WHERE TABLE_NAME=?",
  undef, "TEST");
......

    我们可以看到同取得单行不一样的是, 没有fetchall_hashref这个函数, 但fetchall_arrayref也可以将记录以hash的方式返回. 如一个查返回col1, col2, col3, 则下面的代码返回的每一行记录就是一个hash:

my $rows = $sth->fetchall_arrayref(
   col1=>1, col2=>1,   col3=>1 };
  
foreach my $row (@$rows)
{
   print($row->{col2});
   print($row->{col1});
}

    但这种将所有记录一次拉到客户端内存的方式在数据量大的情况是不行的, 因此我们需要能指定一次fetch返回多少条记录, 可以用如下方法:

my $BATCH_SIZE=100;
......
my $last_fetch = 0;
while(!$last_fetch)
{
   $array_ref = $sth->fetchall_arrayref(undef, $BATCH_SIZE);
   $last_fetch = 1 if (@$array_ref < $BATCH_SIZE);
}
......

    知道了这些之后, 用Perl来处理数据库的数据就容易多了.

January 9, 2007

学习Perl DBI -- 数据库连接的高级属性

    1, AutoCommit -- 是否自动提交

    一般来说自动提交不利于应用程序的性能.

$dbh->{AutoCommit} = 1;
print "AutoCommit: $dbh->{AutoCommit}\n";

    2, ChopBlanks -- 取舍CHAR类型后面的空格

    当你从数据库中取CHAR类型的值时, 你可以指定要不要带后面的空格, 在数据库中CHAR是定长的, 长足不足时, 后面以空格补充, 但你在写应用程序时, 可能并不想要后面的空格, 这时你可以将这个选项设为1.

$dbh->{ChopBlanks} = 1;
print "ChopBlanks: $dbh->{ChopBlanks}\n";

    3, LongTruncOK -- 是否允许载断返回值

    如果返回值(如Long或LOB类型)的值大于缓冲区的长度, 有两个选项, 一种是报错, 另一种是只取缓冲区的长度的值, 丢弃后面的值. 设为True, 则不报错而只取一部份值, 设为False则报错.

$dbh->{LongTruncOk} = 1;
print "LongTruncOk: $dbh->{LongTruncOk}\n";

    4, LongReadLen -- 指定Long或LOB缓冲的最长大度

    在数据库中, Long或LOB类型可以存放2GB或更多的值, 在Perl应用程序去取这些值时, 必须要指定一个最大的缓冲区大小, 和LongTruncOk配合, 可以取出一定长度的值.

$dbh->{LongReadLen} = 1048576;
print "LongReadLen: $dbh->{LongReadLen}\n";

上一页 1 2 3 4 5 6 7 8 9 10 11 下一页

当前分类: Developer

Creative Commons License
本站版权: 共用创作 CC
署名-非商业性-相同方式分享
本站基于MT-3.36免费版
(©)版权所有, 2004 - 2008, www.AnySQL.net, 保留所有权利.
MSN: loufangxin(a)msn.com, Mail: anysql(at)126.com/support(at)iamdba.com, Skype ID:anysql