【问题标题】:Perl DBI dynamic fetchrow while loopsPerl DBI 动态 fetchrow while 循环
【发布时间】:2010-10-26 12:58:39
【问题描述】:

我正在尝试将表名传递给一个获取该表的所有字段名的子程序,将它们存储到一个数组中,然后将该数组与另一个 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())

【问题讨论】:

    标签: perl dynamic loops dbi while-loop


    【解决方案1】:

    使用 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
    • for中的打印应该是: print "\t$col is $row->{ $col }\n";
    • 哎呀,这就是我没有测试的结果。
    • 可能值得一提的是在调用 DBI->connect 时设置 FetchHashKeyName 以消除可能不区分大小写的大写/小写列名被用作区分大小写的哈希键的陷阱。因此,例如,我总是连接指定 FetchHashKeyName => 'NAME_lc' 以保证表示列名的哈希键是小写的,即使数据库返回它们是 CamelCased。
    • @araqnid 我是在您留下评论时添加的。
    【解决方案2】:

    我想知道这种方法是否适用于空表。

    获取列元数据最安全的方法不是查看返回的 hashref 的键(可能不存在),而是按照规则进行操作并使用 DBI 提供的 $sth 本身的属性:

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

    有关详细信息,请参阅 DBI 手册页的元数据部分。

    【讨论】:

      猜你喜欢
      • 2013-03-23
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 2014-11-14
      • 2015-03-27
      • 2019-02-07
      • 2012-11-29
      • 1970-01-01
      相关资源
      最近更新 更多