2012-04-17 4 views
0

私はクエリの結果を2度使いたいと思います。
ポインタを再配置して、最初から2回目の結果を読み始めるにはどうすればよいですか? (ただ簡単にするためにスクリーニングするための印刷)以下
例: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ライブラリはファイル全体をメモリにロードして1行ずつ読み込むとは思っていないので、なぜデータベースライブラリから期待していますか?

その他、全く必要ありません。完全な結果を簡単に読み込むことができます。

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のSTHが必要な場合は、DBD::Spongeにデータをロードすることができます。

+0

ありがとうございました:) –

+0

巨大なファイルを扱う場合、一般にループアプローチがファイルを一度にスラーピングするよりも好まれます。大きなデータセットにも同じことが言えます。ですから、IMHOは不必要ではありません。 – dgw

+0

@dgw、OPが望む機能を得るために、DBIは結果セット全体をメモリに自動的にスラップしなければならないでしょう!あなたは実際に私に同意しています。 – ikegami

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を検索しようとしたことを忘れてしまった。それはうまくいきませんでした。 –

+0

よく '@ data'はファイルハンドルではなく配列なので、' seek'を使うのは意味がありません。 '$ sth'で' seek 'を実行しようとすると '' GLOBリファレンスではありません...' 'というエラーが発生します。データベースから再度データを読み取ることができない場合や、そのデータを再度読み取る必要がない場合は、おそらく何らかの種類の(Perl)データ構造で保存するか、ファイルに書き込む必要があります。 –

+0

Ew ...だからそれを読んだら...それはなくなってしまった!私はperlがこのエリアに限られているのに驚いています...それはどこかに保存しなければなりません!それが既にあるように見えるときに配列に格納するコードを追加するのは残念です! –