【发布时间】:2014-01-24 03:30:04
【问题描述】:
这是一个关于 Perl 数据结构的问题,但首先是对所涉及的一些细节的简要描述。我有一个使用 DBI 并针对 mysql 数据库($q1 $q2 $q3)执行三个查询的 perl 脚本。每个查询返回 2 或 3 个字段(根据要求可能会有所变化)和任意数量的行。我的最终输出需要是所有字段及其值的 csv。
以下表示从数据库返回的字段和行。
如果 $q1 返回
field1 field2
id1 val_a
id2 val_w
$q2
field3 #note $q2 has returned one row
000
$q3
field4 field5 field6
val_b val_c val_d
val_x val_y val_z
那么 csv 将是
field1,field2,field3,field4,field5,field6
id1,val_a,000,val_b,val_c,val_d
id2,val_w,,val_x,val_y,val_z
我试图用这样的数组散列来收集数据
my @statements = ($q1,$q2,$q3);
my %HoA;
for (@statements) {
my $sth = $dbh->prepare($_);
$sth->execute;
my $i=0;
while(my @row = $sth->fetchrow_array) {
push ( @{ $HoA{$i} }, @row[0..$#row] );
$i++;
}
}
我仍在学习,所以我不确定这是否是最佳选择,尽管它一直对我有用除了当一个或多个查询返回的行数少于其他查询时,这是在上面的示例中说明了返回的字段和行。这会导致数据结构中断,行将相互碰撞。我还尝试了哈希哈希,使用内部哈希键的字段
my @statements = ($q1,$q2,$q3);
my %HoH;
for (@statements) {
my $sth = $dbh->prepare($_);
$sth->execute;
my $fields_ref = $sth->{NAME_lc};
my $i=0;
while(my @row = $sth->fetchrow_array) {
my $v=0;
for my $field (@$fields_ref) {
$HoH{$i}{$field}=$row[$v];
$v++;
}
$i++;
}
}
这遇到了另一个问题,不存在的行的字段的内部键将不会被创建。因此,带有 Data::Dumper 的打印件(例如我的问题开头的示例)将如下所示:
'0' => {
'field1' => 'id1',
'field2' => 'val_a',
'field3' => '000',
'field4' => 'val_b',
'field5' => 'val_c',
'field6' => 'val_d',
},
'1' => {
'field1' => 'id2',
'field2' => 'val_w', # no field3
'field4' => 'val_x',
'field5' => 'val_y',
'field6' => 'val_z',
},
所以我有点卡住了,不知道接下来要尝试什么...也许有一种方法可以保留 field3 的密钥并为其赋予类似 null 的值?有什么帮助吗?
【问题讨论】:
-
我想知道你在读什么 .. $sth->fetchrow_array .. 是从你创建的 CSV 文件还是从数据库 .. 如果它来自 CSV 那么如何您是否正在创建 CSV 以防缺失值
-
@Gaurav 这三个查询是针对 mysql 数据库运行的。我正在读取从数据库返回的数据
-
你能像 Gaurav 要求的那样发布
$sth->fetchrow_array的返回值吗?没有它,目前还不清楚发生了什么。在while循环行之后,请添加print Data::Dumper->Dump([\@row], [qw(row)]);您还需要一个use Data::Dumper()才能使用此功能。 -
@rzrgenesys187 我尝试了一个简化的示例来说明问题第一部分中 db 返回的内容,因此 $sth->fetchrow_array 将我示例中的行以数组的形式返回。
标签: perl hash-of-hashes