开发者

Perl Array Dereference Problem with DBI::fetchall_arrayref

开发者 https://www.devze.com 2023-03-14 15:00 出处:网络
I\'m a Perl newbie and am having issues with dereferencing an array that is a result of fetchall_arrayref in the DBI module:

I'm a Perl newbie and am having issues with dereferencing an array that is a result of fetchall_arrayref in the DBI module:

my $开发者_JS百科sql = "SELECT DISTINCT home_room FROM $classlist";
my $sth = $dbh->prepare($sql);
$sth->execute;
my $teachers = $sth->fetchall_arrayref;
foreach my $teacher (@{$teachers}) {
    print $teacher;
}

Running this will print the reference instead of the values in the array.

However, when I run:

my $arrref = [1,2,4,5];
foreach (@{$arrref}) {
print "$_\n";
}

I get the values of the array.

What am I doing wrong? Thank you for your help!

Jeff


From the doc

The fetchall_arrayref method can be used to fetch all the data to be returned from a prepared and executed statement handle. It returns a reference to an array that contains one reference per row.

So in your example, $teacher is an ARRAY ref. So you will need to loop through this array ref

foreach my $teacher (@{$teachers}) {
    foreach my $titem (@$teacher) {
        print $titem;
    }
}


if you want to extract only the teacher column, you want to use:

my @teachers = @{$dbh->selectcol_arrayref($sql)};


fetchall_arrayref fetches all the results of the query, so what you're actually getting back is a reference to an array of arrays. Each row returned will be an arrayref of the columns. Since your query has only one column, you can say:

my $teachers = $sth->fetchall_arrayref;
foreach my $teacher (@{$teachers}) {
    print $teacher->[0];
}

to get what you want.

See more:

Arrays of arrays in Perl.


You have a reference to an array of rows. Each row is a reference to an array of fields.

foreach my $teacher_row (@$teachers) {
    my ($home_room) = @$teacher_row;
    print $home_room;
}

You would have seen the difference with Data::Dumper.

use Data::Dumper;
print(Dumper($teachers));
print(Dumper($arrref));


$sth->fetchall_arrayref returns a reference to an array that contains one reference per row!
Take a look at DBI docs here.


Per the documentation of DBI's fetchall_arrayref():

The fetchall_arrayref method can be used to fetch all the data to be returned from a prepared and executed statement handle. It returns a reference to an array that contains one reference per row.

You're one level of indirection away:

my $sql = "SELECT DISTINCT home_room FROM $classlist";
my $sth = $dbh->prepare($sql);
$sth->execute;
my $teachers = $sth->fetchall_arrayref;
foreach my $teacher (@{$teachers}) {
    local $" = ', ';
    print "@{$teacher}\n";
}

The data structure might be a little hard to visualize sometimes. When that happens I resort to Data::Dumper so that I can insert lines like this:

print Dumper $teacher;

I've found that sometimes by dumping the datastructure I get an instant map to use as a reference-point when creating code to manipulate the structure. I recently worked through a real nightmare of a structure just by using Dumper once in awhile to straighten my head out.


You can use map to dereference the returned structure:

@teachers = map { @$_->[0] } @$teachers;

Now you have a simple array of teachers.

0

精彩评论

暂无评论...
验证码 换一张
取 消