2012-04-17 44 views
0

我想使用兩次查詢的結果。
如何重新定位指針以開始第二次開始讀取結果?
實例下(只是打印篩選簡單):如何重新讀取perl數據庫查詢結果

if ($dbh = DBI->connect("DBI:mysql:database=tng;host=ip", "username", "password")) { 
    $strSQL = "select * from table"; 
    if ($strQuery = $dbh->prepare($strSQL)) { 
     if ($strQuery->execute()) { 
      while (@data = $strQuery->fetchrow_array()) { 
       print $data[0]; 
      } 
      --reposition to top and reread the query result and do something else with the data-- $strQuery->finish; 
     } 
     else { 
      $strMsg = "$strDateTime ERROR -- unable to execute statement: " . $strQuery->errstr . "\n"; 
      print logFile "$strMsg"; 
     } 
    } 
    else { 
     $strMsg = "$strDateTime ERROR -- unable to prepare statement: " . $dbh->errstr . "\n"; 
     print logFile "$strMsg"; 
    } 
    $dbh->disconnect(); 
} 
else { 
    print logFile "$strDateTime ERROR -- unable to connect to iptables database ... " . DBI->errstr . " \n"; 
} 

回答

4

您不希望IO庫將整個文件加載到內存中以逐行讀取它,那麼爲什麼您期望從數據庫庫中讀取它呢?

此外,這是完全沒有必要的。加載完整的結果非常容易。

my $sth = $dbh->prepare($sql); 
my $data = $dbh->selectall_arrayref($sth); 

for my $row (@$data) { 
    my ($col1, $col2, ...) = @$row; 
    ... 
} 

for my $row (@$data) { 
    my ($col1, $col2, ...) = @$row; 
    ... 
} 

如果您需要DBI,您可以將數據加載到DBD::Sponge中。

+0

謝謝一堆:) – 2012-04-18 04:31:59

+0

當處理巨大的文件時,循環方法通常優先於一次sl the文件。同樣適用於大型數據集。所以問題是恕我直言,沒有必要。 – dgw 2012-04-18 08:02:20

+0

@dgw,獲得OP所需的功能,DBI將不得不將整個結果集自動揣入內存!你實際上同意我的觀點。 – ikegami 2012-04-18 09:41:37

1

我正要說,你不能做到這一點,但它看起來好像你可以,你只需要execute的聲明再次處理。請注意,此代碼使用PostgreSQL,因爲我使用它(並且沒有安裝MySQL),但它也適用於您。

use strict; 
use warnings; 
use DBI; 
my $dbh=DBI->connect("dbi:Pg:dbname=db;host=hosty-host-host","username","password") 
    or die DBI->errstr; 

my $sth=$dbh->prepare("select generate_series(1,5)") or die $dbh->errstr; 
$sth->execute or die $dbh->errstr; 

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

print "\nSecond verse, same as the first!\n\n"; 
$sth->execute or die $dbh->errstr; 

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

$sth->finish; 
$dbh->disconnect; 

輸出是:

1 
2 
3 
4 
5 

Second verse, same as the first! 

1 
2 
3 
4 
5 

順便說一句,我想通過看err and/or errstr而不是用一堆if-else語句的推薦錯誤檢查。

編輯補充:如果你不想execute聲明再次處理(和重讀從數據庫中的信息),你可能會卡住或者a)存儲在(Perl的)數據結構中的數據或b)將其寫入文件,然後從文件中讀取(並根據需要多次在文件句柄上使用seek)。

+0

但我認爲執行是重新查詢數據庫,它可能已經改變。另外,我忘了提及我試圖找@data,0,0;這並沒有奏效。 – 2012-04-17 22:06:38

+0

那麼'@ data'是一個數組,不是文件句柄,因此使用'seek'就沒有意義了。在'$ sth'上嘗試'seek'會導致錯誤「」在...處不是GLOB引用「。如果你不能或不想再從數據庫讀取數據,那麼你可能不得不將它保存在某種(Perl)數據結構中,或者將它寫入文件。 – 2012-04-17 22:11:19

+0

Ew ...所以一旦你讀了它...它不見了!我很驚訝,perl在這個領域是有限的......它必須存儲在某個地方!當它看起來已經存在時,添加更多的代碼來存儲數組是非常遺憾的! – 2012-04-17 22:16:27