简体   繁体   English

DBI :: fetchall_arrayref的Perl数组取消引用问题

[英]Perl Array Dereference Problem with DBI::fetchall_arrayref

I'm a Perl newbie and am having issues with dereferencing an array that is a result of fetchall_arrayref in the DBI module: 我是Perl新手,在解引用数组时遇到问题,该数组是DBI模块中fetchall_arrayref的结果:

my $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. fetchall_arrayref方法可用于从准备和执行的语句句柄中获取所有要返回的数据。 It returns a reference to an array that contains one reference per row . 它返回对数组的引用,该数组每行包含一个引用

So in your example, $teacher is an ARRAY ref. 因此,在您的示例中, $teacher是ARRAY引用。 So you will need to loop through this array ref 因此,您将需要遍历此数组引用

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

如果您只想提取教师列,则可以使用:

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. fetchall_arrayref获取查询的所有结果,因此您实际上要返回的是对数组数组的引用。 Each row returned will be an arrayref of the columns. 返回的每一行将是各列的arrayref。 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 . 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 . 您会看到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! $sth->fetchall_arrayref返回对数组的引用,该数组每行包含一个引用!
Take a look at DBI docs here . 这里看看DBI文档。

Per the documentation of DBI's fetchall_arrayref() : 根据DBI的fetchall_arrayref()文档:

The fetchall_arrayref method can be used to fetch all the data to be returned from a prepared and executed statement handle. fetchall_arrayref方法可用于从准备和执行的语句句柄中获取所有要返回的数据。 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: 发生这种情况时,我求助于Data::Dumper以便可以插入如下代码:

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. 最近,我不时地使用Dumper来理清头绪,经历了一个结构的真实噩梦。

You can use map to dereference the returned structure: 您可以使用map取消引用返回的结构:

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

Now you have a simple array of teachers. 现在您有了一个简单的教师队伍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM