Проблема разыменования массива Perl с DBI::fetchall_arrayref

Я новичок в Perl, и у меня проблемы с разыменованием массива, который является результатом fetchall_arrayref в модуле DBI:

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;
}

Запуск этого приведет к печати ссылки вместо значений в массиве.

Однако, когда я запускаю:

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

Я получаю значения массива.

Что я делаю не так? Спасибо за помощь!

Джефф


person Jeff Erickson    schedule 22.06.2011    source источник


Ответы (7)


если вы хотите извлечь только столбец учителя, вы хотите использовать:

my @teachers = @{$dbh->selectcol_arrayref($sql)};
person paul    schedule 22.06.2011

Из документа.

Метод fetchall_arrayref можно использовать для получения всех данных, которые должны быть возвращены из подготовленного и выполненного дескриптора оператора. Он возвращает ссылку на массив, содержащий по одной ссылке на строку.

Итак, в вашем примере $teacher - это ссылка на МАССИВ. Итак, вам нужно будет пройти через этот массив ref

foreach my $teacher (@{$teachers}) {
    foreach my $titem (@$teacher) {
        print $titem;
    }
}
person ccheneson    schedule 22.06.2011

fetchall_arrayref извлекает все результаты запроса, поэтому на самом деле вы получаете ссылку на массив массивов. Каждая возвращаемая строка будет ссылкой на массив столбцов. Поскольку ваш запрос имеет только один столбец, вы можете сказать:

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

чтобы получить то, что вы хотите.

Узнать больше:

Массивы массивов в Perl.

person friedo    schedule 22.06.2011

У вас есть ссылка на массив строк. Каждая строка является ссылкой на массив полей.

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

Вы бы заметили разницу с Data::Dumper.

use Data::Dumper;
print(Dumper($teachers));
print(Dumper($arrref));
person ikegami    schedule 22.06.2011

$sth->fetchall_arrayref возвращает ссылку на массив, содержащий по одной ссылке на строку!
Посмотрите документы DBI здесь.

person cirne100    schedule 22.06.2011

Согласно документации fetchall_arrayref() 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}) {
    local $" = ', ';
    print "@{$teacher}\n";
}

Структуру данных иногда бывает трудно визуализировать. Когда это происходит, я прибегаю к Data::Dumper, чтобы вставить такие строки:

print Dumper $teacher;

Я обнаружил, что иногда, сбрасывая структуру данных, я получаю мгновенную карту, которую можно использовать в качестве ориентира при создании кода для управления структурой. Недавно я пережил настоящий кошмар со структурой, просто время от времени используя Dumper, чтобы привести себя в порядок.

person DavidO    schedule 22.06.2011

Вы можете использовать карту для разыменования возвращаемой структуры:

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

Теперь у вас есть простой набор учителей.

person paz9    schedule 27.07.2013
comment
Я должен упомянуть, что @ перед $_ вызовет устаревшее предупреждение в более поздних версиях perl. Просто удалите его, чтобы успокоить это. - person paz9; 29.07.2013