in reply to DBI::fetchall_arrayref() error

You need to add an explicit row count check before your inner for loop to prevent infinite loop:

while (my $rows = $sth->fetchall_arrayref(undef, 3)) { # ^ this condition is always true # why? because when there is nothing to fetch, # $rows is reference to an empty array, not undef last if ($#$rows < 0); # break out of infinite loop for (@$rows) { ...

I am using version 1.39 of DBI and I could not repeat the same error, fetch without execute, as you have indicated.

Replies are listed 'Best First'.
Re: Re: DBI::fetchall_arrayref() error
by pg (Canon) on Jan 12, 2004 at 01:55 UTC

    No.

    I tried this piece of code, it fails with the same error:

    use DBI; use Data::Dumper; use strict; my $dbh = DBI->connect('dbi:ODBC:TestingDB',"","",{RaiseError => 1, Au +toCommit=>1}) || die "failed"; my $sth = $dbh->prepare("select cof_name, price from coffees") or die; $sth->execute or die; while (my $rows = $sth->fetchall_arrayref([0,1]), 3) { last if ($#$rows < 0); } $dbh->disconnect();

    And this does not explain why it works, if you change [0] to undef. Even if what you said is right, should not fetchall_arrayref gives user the same interface, with undef and [0].

      Hi pg, I used the following to do the test earlier:
      #!C:/Perl/bin/perl use strict; use DBI; use DBD::Sybase; use Data::Dumper; my $dbh = DBI->connect("dbi:Sybase:server=SERVER;database=DATABASE", + "USER","PASSWORD") or die "Can not connect to database!"; my $sth = $dbh->prepare( qq{ select amount from trades_gdw_total }); $sth->execute(); while (my $rows = $sth->fetchall_arrayref([0], 3)) { last if ($#$rows <= 0); for (@$rows) { print "got @$_\n"; } print "---\n"; }

      And I got the desired behaviour, with no errors reported. I am using DBI version 1.39, with DBD::Sybase, by the way.

      I studied the source code of DBI, and extracted the following code concerning the behaviour of fetchall_arrayref:
      # we copy the array here because fetch (currently) always # returns the same array ref. XXX if ($slice && @$slice) { # if called with [0] $max_rows = -1 unless defined $max_rows; push @rows, [ @{$row}[ @$slice] ] while($max_rows-- and $row = $sth->fetch); } elsif (defined $max_rows) { # if called with undef $max_rows = -1 unless defined $max_rows; push @rows, [ @$row ] while($max_rows-- and $row = $sth->fetch); } else { push @rows, [ @$row ] while($row = $sth->fetch); }

      And everything points to fetch.

        Base on my conversation with Roger, both of us suspect this problem might be DBD dependent (or platform dependent?).

        Sounds like fetchall_arrayref() does not handle boundary nicely all the time.

        Although I didn't reply dbwiz, with the combination of my environment, his solution also failed.