perl DBI 學習總結

aaqwsh發表於2011-01-16
perl DBI 學習總結
DBI和DBD的不同關係模型:

perl >> perl-DBI >>DBD

DBI的設計的作用是使用你忽略不同廠商的庫的細節。它為你想要使用的SQL查詢提供簡單的介面。DBI不知道怎樣和不同的資料庫部分進行交流,但是它知道怎樣找到和載入DBD(Database Driver)模組。在DBD模組裡,有不同廠商的庫,並且DBD知道怎樣去和真正的資料庫交流。對於不同的資料庫,有一個DBD模組。

當你想讓DBI做一個查詢的時候,它會傳送這個查詢給適當的DBD模組,DBD將和真正的資料庫互動。當它得到返回結構時,它將結果傳送給DBI。然後DBI將結果給你。所以,你的程式只需要和DBI進行互動,而不是和真正的資料庫。


##########################################################################
可移植的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);
②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)的路徑名。
##########################################################################
##########################################################################
連線Informix資料庫取資料:------
#!/usr/bin/perl
use DBI;
use DBD::Informix;
my @field;
my @sql_list;
my @cmd_list;
my $time_stamp;
my $time_stamp2;
my $w_file;
my $count=0;
my $vendor=shift;
my $db_type=shift;
my $db_server=shift;
my $user_name=shift;
my $password=shift;
my $omc_name=shift;
my $src_dir=shift;
my $desc_dir=shift;
my $cmd_list=shift;
my $sql_list=shift;
#獲取當前時間並開啟寫檔案
my ($sec,$min,$hour,$mday,$mon,$year)=(localtime)[0,1,2,3,4,5];
$year=$year + 1900;
$mon=$mon+1;
$mon=sprintf("%02d",$mon);
$mday=sprintf("%02d",$mday);
$hour=sprintf("%02d",$hour);
$min=sprintf("%02d",$min);
$sec=sprintf("%02d",$sec);
$time_stamp=$year.$mon.$mday.$hour.$min.$sec;
$time_stamp2=$year."-".$mon."-".$mday." ".$hour.":".$min.":".$sec;
#連線資料庫
print "開始連線$db_type資料庫[DataBaseServer:$db_server]...\n";
my $dbh = DBI->connect("dbi:$db_type:$db_server","$user_name","$password",{PrintError => 0});
if($dbh){
 print "連線$db_type資料庫成功[DataBaseServer:$db_server]...\n";
}else{
 print "連線$db_type資料庫失敗[DataBaseServer:$db_server]...\n";
 exit(1);
}
for($i=0;$i #組合檔名並開啟寫檔案
 $vendor=uc($vendor);
 $omc_name=uc($omc_name);
 $cmd_list[$i]=lc($cmd_list[$i]);
 $file_name="MSS#$vendor#$omc_name#$cmd_list[$i]#$time_stamp#100#";
 open(WFILE,">$src_dir/$file_name") || die "開啟檔案失敗!\n";
 #執行SELECT語句並獲取資料
 $sql_list[$i]=~s/\n/\n /g;
 print "執行SQL語句:\n[$sql_list[$i]]\n";
 my $sth = $dbh->prepare(qq{$sql_list[$i]});
 $sth->execute();
 print "執行SQL語句成功...\n";
 #讀取記錄資料
 while(@field=$sth->fetchrow_array){
   write_file(WFILE,($omc_name));
  write_file(WFILE,(@field));
  write_file(WFILE,($time_stamp2));
  print WFILE "\n";
  $count++;
 }
 close(WFILE);
 if($count eq 0){
  print "沒有獲取到記錄...\n\n";
  system("rm -f $src_dir/$file_name");
 }else{
  $file_name_src=$file_name."0.src";
  print "成功獲取$count條記錄...\n";
  print "生成檔案[$file_name_src]...\n\n";
  system("mv -f $src_dir/$file_name $desc_dir/$file_name_src");
 }
 $count=0;
 $sth->finish();
}
#關閉資料庫連線
$dbh->disconnect();
print "關閉$db_type資料庫連線[DataBaseServer:$db_server]...\n";
sub trim
{
 my ($line)=@_;
 $line=~s/^[ \t]+//;  #替換掉開頭空格
 $line=~s/[ \t\r\n]+$//;#替換掉結尾空格
 return $line;
}
sub  write_file
{
 my $i=0;
 my ($W_FILE,@row_data)=@_;
 my $col_num=@row_data;
 for($i=0;$i {
  $row_data[$i]=trim($row_data[$i]);
  print $W_FILE $row_data[$i]."|";
 }
}
 
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/like_zhz/archive/2010/04/02/5441946.aspx

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/758322/viewspace-683946/,如需轉載,請註明出處,否則將追究法律責任。