2012-04-17 4 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 sth가 필요한 경우 데이터를 에로드 할 수 있습니다.

+0

감사합니다. –

+0

거대한 파일을 다룰 때 일반적으로 한 번에 파일을 slurping하는 것보다 루프 접근이 더 좋습니다. 대형 데이터 세트에도 동일하게 적용됩니다. 따라서 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보고이 아닌 경우 - 다른 문장의 무리를 사용하여 오류 검사를 권하고 싶습니다.

추가 편집 :을 당신이 문을 다시 처리 (데이터베이스에서 정보를 다시 읽어) execute하지 않으려면, 당신은 아마 중 하나)에 붙어 (펄) 데이터 구조에 데이터를 저장하고 또는 b) 파일에 쓰고 파일에서 읽어들입니다 (파일 핸들에서 seek을 원하는만큼 여러 번 사용합니다).

+0

하지만 실행이 변경되었을 수있는 데이터베이스를 다시 쿼리한다고 생각합니다. 또한, 나는 @data, 0, 0을 찾아 보았습니다. 그리고 그것은 작동하지 않았다. –

+0

음'@ data'는 파일 핸들이 아닌 배열입니다. 따라서'seek'를 사용하는 것은 의미가 없습니다. '$ sth'에서'seek '을 시도하면''GLOB 참조가 아닙니다 ...' '라는 오류가 발생합니다. 데이터베이스의 데이터를 다시 읽을 수 없거나 읽지 않으려는 경우에는 일종의 (Perl) 데이터 구조로 저장하거나 파일에 기록해야합니다. –

+0

Ew ... 그래서 일단 읽으면 ... 사라졌어! 나는 perl이이 지역에 제한되어 있다는 것에 놀랐습니다 ... 어딘가에 그것을 저장해야합니다! 이미있는 것처럼 보이면 더 많은 코드를 배열에 저장하는 것이 부끄러운 일입니다! –

관련 문제