my $dbh = DBI->connect('...', { RaiseError => 0 }) or die "Unable to connect to datasource: $DBI::errstr\n"; my $sth = $dbh->prepare('SELECT PK, Name, Memo...'); or die "Unable to prepare query statement: $DBI::errstr\n"; my $rv = $sth->execute() or die "Unable to execute query statement: $DBI::errstr\n"; my $data = $sth->fetchall_arrayref; my %hash = %{ &checksums($data) }; # some time later... foreach(@$data) { print "PK:\t", $_->[0], "\t"; print "Name:\t", $_->[1], "\t"; print "Digest:\t", $hash{$_->[0]}, "\n"; } sub checksums { my $recordset = shift; my %checksums; foreach(@$recordset) { $checksums{$_->[0]} = &digest($_->[2]); } return \%checksums; }
...untested, of course. That may not even work, it depends on exactly what fetchall_arrayref does.
Otherwise, maybe you can alias or copy the statement handle, although I'm not sure how that would work. If you're feeling ambitious, you could write a wrapper for DBI that caches the statement handle in memory and allows you to manipulate the cursor. Actually, there may already be a module to do that. Check CPAN. =) If you're feeling lazy, maybe you can just run the same query twice and generate two equivalent recordsets. Eew!
When I hear about problems like this I can't help but imagine there's a better way to approach the issue. If you can rewrite your code to avoid having to loop through the recordset twice, that might be the best solution. (see below for a rewrite of the above code)
Good luck,
'kaboo
(this node has been updated)
my @data; while($sth->fetch) { push @data, { PK => $_->[0], Name => $_->[1], Memo => $_->[2], Digest => &digest($_->[2]) }; } # some time later... foreach(@data) { print "PK:\t", $_->{PK}, "\t"; print "Name:\t", $_->{Name}, "\t"; print "Digest:\t", $_->{Digest}, "\n"; }
Not the strongest example, but you get the idea. :)
In reply to Re: Reusing DBI Statement Handle
by mwp
in thread Reusing DBI Statement Handle
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |