Perl DBI динамическая выборка строки во время циклов

Я пытаюсь передать имена таблиц в подпрограмму, которая получает все имена полей этой таблицы, сохраняет их в массив, а затем использует этот массив в сочетании с fetchrow другого запроса sql для отображения данных в этих полях. Вот код, который у меня есть сейчас:

Примеры подвызовов с именами таблиц в качестве параметра:

shamoo("reqhead_rec");
shamoo("approv_rec");
shamoo("denial_rec");

шампунь саб:

sub shamoo
{
    my $table = shift;
    print uc($table)."\n=====================================\n";

    #takes arg (table name) and stores all the field names into an array
    $STMT = <<EOF;
    select first 1 * from $table
    EOF

    my $sth = $db1->prepare($STMT);$sth->execute;

    my ($i, @field);
    my $columns = $sth->{NAME_lc};
    while (my $row = $sth->fetch){for $i (0 .. $#$row){$field[$i] = $columns->[$i];}}

    $STMT = <<EOF;
    select * from $table where frm = '$frm' and req_no = $req_no
    EOF
    $sth = $db1->prepare($STMT);$sth->execute;
    $i=0;
    while ($i!=scalar(@field))
    {
    #need code for in here...
    }
}

Я ищу способ превратить это во что-то, что не нужно явно определять....

my ($frm, $req_no, $auth_id, $alt_auth_id, $id_acct, $seq_no, $id, $appr_stat, $add_date, $approve_date, $approve_time, $prim);
while(($frm, $req_no, $auth_id, $alt_auth_id, $id_acct, $seq_no, $id, $appr_stat, $add_date, $approve_date, $approve_time, $prim) = $sth->fetchrow_array())

person CheeseConQueso    schedule 15.05.2009    source источник


Ответы (2)


Используйте fetchrow_hashref:

sub shamoo {
    my ($dbh, $frm, $req_no, $table) = @_;

    print uc($table), "\n", "=" x 36, "\n";

    #takes arg (table name) and stores all the field names into an array
    my $sth = $dbh->prepare(
        "select * from $table where frm = ? and req_no = ?"
    );

    $sth->execute($frm, $req_no);

    my $i = 1;
    while (my $row = $sth->fetchrow_hashref) {
        print "row ", $i++, "\n";
        for my $col (keys %$row) {
            print "\t$col is $row->{$col}\n";
        }
    }
}

Вы также можете установить FetchHashKeyName в "NAME_lc" или "NAME_uc" при создании дескриптора базы данных:

my $dbh = DBI->connect(
    $dsn,
    $user,
    $pass,
    {
        ChopBlanks       => 1,
        AutoCommit       => 1,
        PrintError       => 0,
        RaiseError       => 1,
        FetchHashKeyName => "NAME_lc",
    }
) or die DBI->errstr;
person Chas. Owens    schedule 15.05.2009
comment
(keys %$row) дает мне это - глобальный символ %row требует явного имени пакета в ./req.pl - person CheeseConQueso; 15.05.2009
comment
Печать в for должна быть: print \t$col is $row-›{ $col}\n; - person Anon; 15.05.2009
comment
Ой, это то, что я получаю за то, что не тестировал. - person Chas. Owens; 15.05.2009
comment
Возможно, стоит упомянуть, чтобы установить FetchHashKeyName при вызове DBI-›connect, чтобы сгладить ошибки с именами столбцов, которые, возможно, не чувствительны к регистру в верхнем/нижнем регистре, которые используются в качестве хэш-ключей с учетом регистра. Так, например, я всегда подключаюсь, указав FetchHashKeyName => 'NAME_lc', чтобы хеш-ключи, представляющие имена столбцов, гарантированно были в нижнем регистре, даже если БД возвращает их в CamelCased. - person araqnid; 15.05.2009
comment
@araqnid Я добавлял это, пока вы оставляли комментарий. - person Chas. Owens; 15.05.2009

Интересно, будет ли этот метод работать для пустой таблицы.

Самый безопасный способ получить метаданные столбца — это не смотреть на ключи возвращенного хеш-реф (которого может и не быть), а играть по правилам и использовать предоставленные DBI атрибуты самого $sth:

$sth->{NAME}->[i]
$sth->{NAME_uc}->[i]
$sth->{NAME_lc}->[i]

Подробнее см. в разделе «Метаданные» справочной страницы DBI.

person Ya. Perelman    schedule 15.05.2009