我想在perl中写一个小小的" DBQuery"函数,这样我就可以使用一个内联函数来发送一条SQL语句并接收回来,以及一个散列数组,即一个记录集。但是,我遇到了Perl语法问题(可能还有一些奇怪的指针/引用问题),这阻止了我从数据库中获取的哈希值中打包信息。下面的示例代码演示了此问题。
我可以使用以下语法从数组内的哈希中获取数据" Jim":
1
| print $records[$index]{'firstName'} |
返回"吉姆"
但是如果我首先将数组中的哈希记录复制到它自己的哈希变量中,那么我很奇怪地无法再访问该哈希中的数据:
1 2
| %row = $records[$index];
$row{'firstName'}; |
返回"(空白)
这里是显示问题的完整示例代码。任何帮助表示赞赏:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| my @records = (
{'id' => 1, 'firstName' => 'Jim'},
{'id' => 2, 'firstName' => 'Joe'}
);
my @records2 = ();
$numberOfRecords = scalar(@records);
print"number of records:" . $numberOfRecords ."\
";
for(my $index=0; $index < $numberOfRecords; $index++) {
#works
print 'you can print the records like this: ' . $records[$index]{'firstName'} ."\
";
#does NOT work
%row = $records[$index];
print 'but not like this: ' . $row{'firstName'} ."\
";
} |
嵌套的数据结构包含哈希引用,而不是哈希。
1 2 3 4 5 6 7 8 9
| # Will work (the -> dereferences the reference)
$row = $records[$index];
print"This will work:", $row->{firstName},"\
";
# This will also work, by promoting the hash reference into a hash
%row = %{ $records[$index] };
print"This will work:", $row{firstName},"\
"; |
如果您曾经遇到过深刻的Perl数据结构,则可以通过使用Data :: Dumper进行打印以将其打印为人类可读(和Per??l可分析的)形式而受益。
哈希数组实际上并不包含哈希,而是对哈希的引用。
这行:
1
| %row = $records[$index]; |
为%row分配一个条目。关键是标量:
1
| {'id' => 1, 'firstName' => 'Jim'}, |
哪个是对哈希的引用,但该值为空白。
您真正想做的是:
1 2
| $row = $records[$index];
$row->{'firstName'}; |
否则:
1 2
| $row = %{$records[$index];}
$row{'firstName'}; |
其他人则对哈希与哈希引用进行了评论。我觉得还应该提到的另一件事是您的DBQuery函数-似乎您正在尝试执行DBI中已内置的某些操作?如果我正确理解了您的问题,则您正在尝试复制类似selectall_arrayref:
的内容
This utility method combines"prepare","execute" and"fetchall_arrayref" into a single call. It returns a reference to an array containing a reference to an array (or hash, see below) for each row of data fetched.
要添加到上面的可爱答案中,请允许我补充说,您应该始终,始终,始终(是,三个"总是"是)在代码顶部使用"使用警告"。如果这样做,您将得到警告"参考在-e第1行找到了偶数大小的列表的位置"。
数组中实际具有的是hashref,而不是哈希。如果您不理解此概念,则可能值得阅读perlref文档。
要获取您需要做的哈希
1
| my %hash = %{@records[$index]}; |
例如
1 2 3 4 5 6 7 8 9
| my @records = (
{'id' => 1, 'firstName' => 'Jim'},
{'id' => 2, 'firstName' => 'Joe'}
);
my %hash = %{$records[1]};
print $hash{id}."\
"; |
尽管。我不确定您为什么要这么做,除非出于学术目的。否则,我建议在DBI模块中使用fetchall_hashref / fetchall_arrayref,或使用类似Class :: DBI的方法。
还要注意要使用的一个很好的perl习惯用法是
1 2 3 4
| for my $rowHR ( @records ) {
my %row = %$rowHR;
#or whatever...
} |
遍历列表。