Perl - DBI selectall_arrayref при запросе получения ссылки на не хэш - PullRequest
2 голосов
/ 05 октября 2010

Я очень новичок в Perl (но из фона C #) и пытаюсь переместить некоторые скрипты в окно Windows. Из-за того, что некоторые модули не работают с Windows, я изменил способ подключения к БД. У меня есть база данных sqlserver, и у меня был цикл чтения каждой строки в таблице, а затем в этом цикле был отправлен другой запрос для выбора другой информации. Я был ошибкой, когда два оператора не могут быть выполнены одновременно в одном соединении. Поскольку мой объект подключения является глобальным, я не мог найти простой способ обойти это, поэтому решил сохранить первый набор данных в массиве, используя:

my $query = shift;
    my $aryref = $dbh->selectall_arrayref($query) || die "Could not select to array\n";
    return($aryref);

(это в файле модуля, который называется)

Затем я выполняю цикл foreach (где @ $ s_study - это $ aryref, возвращенный выше)

  foreach my $r_study ( @$s_study ) {
    ~~~             
    my $surveyId=$r_study->{surveyid};  <-------error this line
 ~~~~               
        };

Когда я запускаю это, я получаю сообщение об ошибке "Не ссылка на хэш". Я не понимаю ?! Может ли кто-нибудь помочь!

Бекс

Ответы [ 3 ]

8 голосов
/ 05 октября 2010

Вам необходимо предоставить параметр { Slice => {} } для selectall_arrayref, если вы хотите, чтобы каждая строка сохранялась как хеш:

my $aryref = $dbh->selectall_arrayref($query, { Slice => {} });

По умолчанию возвращается ссылка на массив, содержащий ссылку на массив для каждой строки выбранных данных.

1 голос
/ 05 октября 2010

$r_study->{surveyid} - это хеш-код

$r_study->[0] - это ссылка на массив

это ваша ошибка. Вы должны использовать второй

0 голосов
/ 05 октября 2010

Если у вас есть проблема с методом, тогда хорошим первым шагом будет прочитать документацию по этому методу. Вот ссылка на документацию для selectall_arrayref . Там написано:

Этот служебный метод объединяет «подготовить», «выполнить» и "fetchall_arrayref" в один вызов. Возвращает ссылку на массив, содержащий ссылку на массив (или хэш, см. ниже) для каждого выбранная строка данных.

Поэтому поведение по умолчанию - возвращать ссылку на массив, который содержит ссылку на массив для каждой строки. Это объясняет вашу ошибку. Вы получаете ссылку на массив и пытаетесь трактовать его как ссылку на хеш. Я не уверен, что ошибка может быть намного яснее.

Однако есть интересная часть, где говорится "или хэш, см. Ниже". Читая дальше, мы находим:

Вы можете часто хотеть получить массив строк, где каждая строка хранится как хэш. Это можно сделать просто, используя:

my $emps = $dbh->selectall_arrayref(
    "SELECT ename FROM emp ORDER BY ename",
    { Slice => {} }
);
foreach my $emp ( @$emps ) {
    print "Employee: $emp->{ename}\n";
}

Итак, у вас есть два варианта. Либо переключите свой код, чтобы использовать ссылку на массив вместо ссылки на хэш. Или добавьте к вызову опцию "{Slice => {}}", которая возвратит хэш-ссылку.

Документация понятна. Это стоит прочитать.

...