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);