Perl DBI动态获取while循环的行。

3
我将尝试将表名传递给一个子程序,该子程序获取该表的所有字段名并将它们存储到数组中,然后与另一个SQL查询的fetchrow结合使用,在这些字段中显示数据。以下是我现在拥有的代码:

将表名作为参数进行子调用的示例:

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

Shamoo订阅:
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())
2个回答

15
使用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;

(keys %$row) 给了我这个错误信息 - 全局符号“%row”需要在 ./req.pl 中明确的包名称。 - CheeseConQueso
for 循环中的打印语句应该是:print "\t$col 是 $row->{$col}\n"; - Anon
糟糕,这就是我没有测试的后果。 - Chas. Owens
在调用DBI->connect时设置FetchHashKeyName可能值得一提,以消除使用大小写敏感的哈希键作为大小写不敏感的列名时可能出现的问题。例如,我总是连接指定FetchHashKeyName => 'NAME_lc',以确保表示列名的哈希键始终为小写,即使DB返回它们为CamelCased。 - araqnid
@araqnid 我在你留言的时候添加了那个。 - Chas. Owens

2
我想知道这种方法是否适用于空表。
获取列的元数据的最安全的方法不是查看返回的哈希引用的键(可能不存在),而是按规则操作并使用 $sth 本身提供的DBI属性。
$sth->{NAME}->[i]
$sth->{NAME_uc}->[i]
$sth->{NAME_lc}->[i]

请参阅DBI手册中的元数据部分以获取详细信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接