perl DBI 总结

http://www.cnblogs.com/homezzm/archive/2011/07/22/2113618.htmlhtml

最近在写perl程序进行数据的采集,perl教程在网上少的可怜呐,至少我找到的资料是不多的。在链接数据库方面下面这个博客写的仍是很清晰的,因此就转过来了。mysql

源文地址:http://blog.csdn.net/like_zhz/article/details/5441946sql

DBI和DBD的不一样关系模型:数据库

########################################################################## 可移植的DBI方法: connect 创建到一个数据库服务器的链接 disconnect 断开数据库服务器的链接 prepare 准备执行一个SQL语句 execute 执行准备好的语句 do 准备并执行一个SQL语句 quote 加引号于要插入的字符串或BLOB值 fetchrow_array 做为一个字段数组取出下一行 fetchrow_arrayref 做为一个字段的引用数组取出下一行 fetchrow_hashref 做为一个哈希表的引用取出下一行 fetchall_arrayref 做为一个字段数组取出全部数据 finish 完成一条语句而且让系统释放资源 rows 返回受影响的行数 data_sources 返回可在localhost上获得的数据库的数组 ChopBlanks 控制fetchrow_*方法是否剥去空格 NUM_OF_PARAMS 在准备的语句中的占位(placeholder-参数)的数目 NULLABLE 其列能够是NULL trace 执行调试跟踪 ########################################################################## $dbh 数据库句柄 $sth 语句句柄 $rc 返回代码(常常是一个状态) $rv 返回值(常常是一个行数) ########################################################################## ①connect($data_source, $username, $password) 使用connect方法使得一个数据库链接到数据源。$data_source值应该以DBI:driver_name:开始。以DBD::mysql驱动程序使用connect的例子: $dbh = DBI->connect("DBI:mysql:$database", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user, $password);npm

②disconnect disconnect方法从数据库断开数据库句柄。它通常就在你从程序退出以前被调用。范例: $rc = $dbh->disconnect; prepare($statement) 准备一条由数据库引擎执行的SQL语句而且返回语句句柄($sth),你可使用它调用execute方法。通常地你借助于prepare和execute来处理SELECT语句(和类SELECT语句,例如SHOW、DESCRIBE和EXPLAIN)。范例: $sth = $dbh->prepare($statement) or die "Can't prepare $statement: $dbh->errstr/n"; ③execute execute方法执行一个准备好的语句。对非SELECT语句,execute返回受影响的行数。若是没有行受影响,execute返回"0E0",Perl将它视做零而不是真。对于SELECT语句,execute只是在数据库中启动SQL查询;你须要使用在下面描述的fetch_*方法之一检索数据。范例: $rv = $sth->execute or die "can't execute the query: $sth->errstr; ④do($statement) do方法准备而且执行一条SQL语句而且返回受影响的行数。若是没有行受到影响,do返回"0E0",Perl将它视为零而不是真。这个方法一般用于事先没法准备好(因为驱动程序的限制)或不须要执行屡次(插入、删除等等)的非SELECT语句。范例: $rv = $dbh->do($statement) or die "Can't execute $statement: $dbh- >errstr/n"; ⑤quote($string) quote方法被用来“转义”包含在string中的任何特殊字符并增长所需的外部的引号。范例: $sql = $dbh->quote($string) ⑥fetchrow_array 这个方法取下一行数据而且做为一个字段值数组返回它。范例: while(@row = $sth->fetchrow_array) { print qw($row[0]/t$row[1]/t$row[2]/n); } ⑦fetchrow_arrayref 这个方法取下一行数据而且做为一个对一个字段值数组的引用返回它。范例: while($row_ref = $sth->fetchrow_arrayref) { print qw($row_ref->[0]/t$row_ref->[1]/t$row_ref->[2]/n); } ⑧fetchrow_hashref 这个方法取一行数据而且返回包含字段名/值对的一个哈希表的一个引用。这个方法不如使用上述数组引用那样有效。范例: while($hash_ref = $sth->fetchrow_hashref) { print qw($hash_ref->{firstname}/t$hash_ref->{lastname}/t/ $hash_ref- > title}/n); } ⑨fetchall_arrayref 这个方法被用来得到从SQL语句被返回的全部数据(行)。它返回一个数组的引用,该数组包含对每行的数组的引用。你用一个嵌套循环来存取或打印数据。范例: my $table = $sth->fetchall_arrayref or die "$sth->errstr/n"; my($i, $j); for $i ( 0 .. $#{$table} ) { for $j ( 0 .. $#{$table->[$i]} ) { print "$table->[$i][$j]/t"; } print "/n"; } ⑩finish 便名没有更多的数据将从这个语句句柄取出。你调用这个方法释放语句句柄和任何与它相关的系统资源。范例: $rc = $sth->finish; ⑪rows 返回由最后一条命令改变(更新、删除等)的行数。这一般用在非SELECT的execute语句以后。范例: $rv = $sth->rows; ⑫NULLABLE 返回一个对一个布尔值数组的引用;对数组的每一个成员,一个TRUE值表示该列能够包含NULL值。范例: $null_possible = $sth->{NULLABLE}; ⑬NUM_OF_FIELDS 这个属性代表由一条SELECT或SHOW FIELDS语句返回的字段数目。你能够用它检查一条语句是否返回告终果:一个零值代表一个象INSERT、DELETE或UPDATE的非SELECT语句。范例: $nr_of_fields = $sth->{NUM_OF_FIELDS}; ⑭data_sources($driver_name) 这个方法返回一个数组,它包含在主机'localhost'上的MySQL服务器可获得的数据库名。范例: @dbs = DBI->data_sources("mysql"); ⑮ChopBlanks 这个属性肯定fetchrow_*方法是否将去掉返回值的头和尾的空白。范例: $sth->{'ChopBlanks'} =1; trace($trace_level)   ⑯trace($trace_level, $trace_filename) trace方法开启或关闭跟踪。看成为一个DBI类方法调用时,它影响对全部句柄的跟踪。看成为一个数据库或语句句柄方法调用时,它影响对给定句柄的跟踪(和句柄的将来子孙)。设置$trace_level为2以提供详细的踪影信息,设置$trace_level为0以关闭跟踪。踪影输出缺省地输出到标准错误输出。若是指定$trace_filename,文件以添加模式打开而且全部跟踪的句柄的手被写入该文件。范例: DBI->trace(2); # trace everything DBI->trace(2,"/tmp/dbi.out"); # trace everything to /tmp/dbi.out $dth->trace(2); # trace this database handle $sth->trace(2); # trace this statement handle 你也能够经过设置DBI_TRACE环境变量开启DBI跟踪。将它设置为等价于调用DBI->(value)的数字值,将它设置为等价于调用DBI->(2,value)的路径名。数组

以上是原文内容。服务器


看了一上午perl,而后用了一下午的时间写了下面的采集(用的时间比较多,呵呵),代码没有抽象,高手轻拍。这个采集百万数据从informix到oracle不到10秒钟。

#!/usr/bin/perloracle

use strict; use DBI; use Time::localtime; use Data::Dumper; use Time::Local; use Net::FTP;tcp

my ($para);fetch

if(@ARGV != 1){

$para = 2;
print "\$para = $para\n";

}else{

$para = $ARGV[0];
print "\$para = $para\n";

}

if($para<2){

print "请输入大于等于2的数字!!!\n";
exit;

}

my $npmdb_dbh = DBI->connect("DBI:ODBC:npmdb", "informix","",{RaiseError=>0,PrintError=>0}); my $gisdb_dbh = DBI->connect("DBI:Oracle:gisdb", "gis","",{RaiseError=>1,AutoCommit=>0});

if(!$npmdb_dbh || !$gisdb_dbh) { print"数据库联接失败 \n"; } else { $npmdb_dbh->do("set isolation to dirty read");

my $sel_sql = " select a.first_result,a.ne_id,
                                NVL(CSTRAFFIC_CONV11,0),
                                NVL(CSTRAFFIC_CONV22,0),
                                NVL(CSTRAFFIC_CONV55,0),
                                NVL(TSNBRASSNBRUUL,0),
                                NVL(TSNBRASSNBRUDL,0),
                                NVL(BRUUL,0),
                                NVL(BRUDL,0),
                                NVL(TDDMAXTCP,0),
                                NVL(TDDMEANTCP,0),
                                NVL(NBRERRBLOCKSRECEIVEDCS_CONV55,0),
                                NVL(NBRBLOCKSRECEIVEDCS_CONV55,0),
                                NVL(NBRERRBLOCKSRECEIVEDPS,0),
                                NVL(NBRBLOCKSRECEIVEDPS,0),
                                NVL(SUCCMACDESTAB,0),
                                NVL(SUCCRBESTAB,0),
                                NVL(ATTMACDESTAB,0),
                                NVL(ATTRBESTAB,0),
                                NVL(a.ATTRABASSIGNESTABCS_CONV11,0)+NVL(a.ATTRABASSIGNESTABCS_CONV22,0),
                                NVL(a.SUCCRABASSIGNESTABCS_CONV11,0)+NVL(a.SUCCRABASSIGNESTABCS_CONV22,0),
                                NVL(a.ATTCONNESTAB_1,0)+NVL(a.ATTCONNESTAB_6,0),
                                NVL(a.SUCCCONNESTAB_1,0)+NVL(a.SUCCCONNESTAB_6,0) ,
                                round(NVL(SFB_DIVFLOAT_1(NVL(a.SUCCCONNESTAB_1,0)+NVL(a.SUCCCONNESTAB_6,0),NVL(a.ATTCONNESTAB_1,0)+NVL(a.ATTCONNESTAB_6,0),0,0)*SFB_DIVFLOAT_1(NVL(a.SUCCRABASSIGNESTABCS_CONV11,0)+NVL(a.SUCCRABASSIGNESTABCS_CONV22,0),NVL(a.ATTRABASSIGNESTABCS_CONV11,0)+NVL(a.ATTRABASSIGNESTABCS_CONV22,0),0,0)*100,0),2),
                                NVL(a.ATTRABASSIGNESTABCS_CONV55,0),
                                NVL(a.SUCCRABASSIGNESTABCS_CONV55,0),
                                round(NVL(SFB_DIVFLOAT_1(NVL(a.SUCCCONNESTAB_1,0)+NVL(a.SUCCCONNESTAB_6,0),NVL(a.ATTCONNESTAB_1,0)+NVL(a.ATTCONNESTAB_6,0),0,0)*SFB_DIVFLOAT_1(NVL(a.SUCCRABASSIGNESTABCS_CONV55,0),NVL(a.ATTRABASSIGNESTABCS_CONV55,0),0,0)*100,0),2),
                                NVL(a.ATTCONNESTAB,0),
                                NVL(a.SUCCCONNESTAB,0),
                                NVL(a.ATTRABASSIGNESTABPS,0),
                                NVL(a.SUCCRABASSIGNESTABPS,0),
                                round(NVL(SFB_DIVFLOAT_1(a.SUCCRABASSIGNESTABPS,a.ATTRABASSIGNESTABPS,0,0),0)*NVL(SFB_DIVFLOAT_1(a.SUCCCONNESTAB,a.ATTCONNESTAB,0,0),0)*100,2),
                                NVL(a.NBRRNCRELCSRAB_CONV11,0)+NVL(a.NBRRNCRELCSRAB_CONV22,0),
                                NVL(a.NBRRABCSRELIUCONN_CONV11,0)+NVL(a.NBRRABCSRELIUCONN_CONV22,0),
                                round(SFB_DIVFLOAT_1(NVL(a.NBRRNCRELCSRAB_CONV11,0)+NVL(a.NBRRNCRELCSRAB_CONV22,0)+NVL(a.NBRRABCSRELIUCONN_CONV11,0)+NVL(a.NBRRABCSRELIUCONN_CONV22,0),NVL(a.SUCCRABASSIGNESTABCS_CONV11,0)+NVL(a.SUCCRABASSIGNESTABCS_CONV22,0),0,0)*100,2),
                                NVL(a.NBRRNCRELCSRAB_CONV55,0),
                                NVL(a.NBRRABCSRELIUCONN_CONV55,0),
                                round(SFB_DIVFLOAT_1(NVL(a.NBRRNCRELCSRAB_CONV55,0)+NVL(a.NBRRABCSRELIUCONN_CONV55,0),NVL(SUCCRABASSIGNESTABCS_CONV55,0),0,0)*100,2),
                                NVL(a.NBRRNCRELPSRAB,0)-NVL(a.REL_REQ_PS_16,0)-NVL(a.REL_REQ_PS_40,0),
                                NVL(a.NBRRABPSRELIUCONN,0),
                                round(SFB_DIVFLOAT_1(NVL(a.NBRRNCRELPSRAB,0)+NVL(a.NBRRABPSRELIUCONN,0)-NVL(a.REL_REQ_PS_16,0)-NVL(a.REL_REQ_PS_40,0)- NVL(a.RAB_PS_REL_IU_CONN_16,0)-NVL(a.RAB_PS_REL_IU_CONN_40,0),a.SUCCRABASSIGNESTABPS,0,0)*100,2),
                                NVL(a.NBRBLOCKSRECEIVEDCS_CONV,0),
                                NVL(a.NBRERRBLOCKSRECEIVEDCS,0),
                                round(NVL(SFB_DIVFLOAT_1(a.NBRERRBLOCKSRECEIVEDCS_CONV55,a.NBRBLOCKSRECEIVEDCS_CONV55,0,0)*100,0),2),
                                round(NVL(SFB_DIVFLOAT_1(a.NBRERRBLOCKSRECEIVEDPS,a.NBRBLOCKSRECEIVEDPS,0,0)*100,0),2),
                                NVL(b.ATTOUTCS,0),
                                NVL(b.FAILOUTCS,0),
                                round(SFB_DIVFLOAT_1(NVL(b.ATTOUTCS,0)-NVL(b.FAILOUTCS,0),NVL(b.ATTOUTCS,0),0,0)*100,2),
                                NVL(b.ATTOUTPSUTRAN,0),
                                NVL(b.FAILOUTPSUTRAN,0),
                                round(SFB_DIVFLOAT_1(NVL(b.ATTOUTPSUTRAN,0)-NVL(b.FAILOUTPSUTRAN,0),NVL(b.ATTOUTPSUTRAN,0),0,0)*100,2)
                                
                                from tpc_utrancell_ne a ,TPC_UTRANCELL_HO_NE b,TPC_UTRANCELL_HSPA_NE c
                                
                        where  a.first_result =  current year to hour - $para units hour ||':00:00'
                        and a.first_result = b.first_result
                        and a.first_result = c.first_result
                        and a.ne_id = b.ne_id
                        and a.ne_id = c.ne_id";
                                        
    print"$sel_sql\n";
  my $rsite = $npmdb_dbh->prepare($sel_sql);
    $rsite->execute();
  my $ref_data = $rsite->fetchall_arrayref();
  $rsite->finish;
  
  $gisdb_dbh->do("delete from BTS_PM_TD where first_result <= sysdate - 74/24");
  
  $gisdb_dbh->do("delete from BTS_PM_TD where first_result = to_date(to_char((sysdate - $para/24),'YYYY-MM-DD HH24'),'SYYYY-MM-DD HH24:MI:SS')");

  my $MM = 0;
  foreach my $row (@$ref_data)
  {
      my @data = @$row;
      my $dataLen = @data;
  
      my $gisInc = "insert into BTS_PM_TD  
                                  values (to_date('$data[0]','SYYYY-MM-DD HH24:MI:SS'),$data[1],";
      for(my $HH = 2; $HH < $dataLen; $HH++){
          $gisInc = $gisInc . "'$data[$HH]',";
      }                        
      $gisInc = substr($gisInc,0,length($gisInc) - 1);
                                  
        $gisInc = $gisInc . " )";
    #print"$gisInc   \n";
      #first_result, ne_id, cstraffic_conv11, cstraffic_conv22, cstraffic_conv55, tsnbrassnbruul, tsnbrassnbrudl, bruul, brudl, tddmaxtcp, tddmeantcp, nbrerrblocksreceivedcs_conv55, nbrblocksreceivedcs_conv55, nbrerrblocksreceivedps, nbrblocksreceivedps, succmacdestab, succrbestab, attmacdestab, attrbestab
      $rsite = $gisdb_dbh->do($gisInc);
      $MM++;
      print "$MM\n";
  }    

$gisdb_dbh->do("commit");

} $npmdb_dbh->disconnect(); $gisdb_dbh->disconnect(); exit(0);