我对Perl有点新意,我需要一些关于在阵列之间移动我的Hash of Arrays的帮助。
目前我有一个db模块,它存储一个像这样的数组:
sub getSourceCriteria {
my($self) = shift();
my($sourceId) = shift();
chomp $sourceId;
my(%criteria) =();
$logger->debug("Getting records for Source ID: " . $sourceId);
$dbh=DBI->connect('dbi:ODBC:StkSkrnDB', 'RTETET', 'XXuser01',{ RaiseError => 1, AutoCommit => 0 }) || \
$logger->err_die("Database connection not made: $DBI::errstr\n");
my($sth) = "select a.criteria_id, a.criteria_type, a.criteria_props,a.generalcriteria_id,b.field_id ";
$sth = $sth . "from t_criteria a, t_sourceMapping b where a.generalcriteria_id = (select generalcriteria_id from t_sourcecriteria where source_id =?) ";
$sth = $sth . "and a.criteria_id=b.criteria_id";
my($qry) = $dbh->prepare($sth);
$qry->execute($sourceId) || $logger->error("Could not query for Source Criteria: $DBI::errstr\n");
my(@row)=();
my($tempCount) = 0;
while ( @row = $qry->fetchrow_array ) {
$tempCount = scalar @row;
$logger->debug("Size of retrieved SQL Array : $tempCount");
$criteria{$row[0]} = \@row;
##@{$criteria{$row[0]} } = \@row;
}
return %criteria;
}
我有一个单独的perl脚本,它从上面的代码中读取SQL输出:
foreach my $criteria (keys %criterias) {
@temp = exists( $criterias{$criteria} ) ? @{ $criterias{$criteria} } : ();
##my $tempStr = exists( $criterias{$criteria} ) ? "Yes" : "No";
$arraySize = scalar @temp;
$logger->debug("GENERALCRITERIA_ID is $GENERALCRITERIA_ID and size of array is $arraySize and $temp[0]");
$genCrit_ID = $temp[$GENERALCRITERIA_ID];
$logger->debug("Criteria ID $criteria has Gen Criteria ID $genCrit_ID");
if (0!=$generalCriteria_ID || $generalCriteria_ID != $genCrit_ID ) { ## test for uniqueness
$generalCriteria_ID = -1;
}
else {
$generalCriteria_ID = $genCrit_ID;
}
}# do something with $key and $value
$generalCriteria = $generalCriteria_ID;
}
问题是我一直得到0作为检索到的数组大小(第2个片段),即使我存储数组(在第1个片段中)我检查并获得实际的数组大小。
非常感谢任何帮助/澄清。
修改 在数据库接口代码中添加了更多代码。
答案 0 :(得分:3)
在while
循环中,您将分配给@row
,然后存储对该数组的引用。但是,每次循环迭代时,您将替换@row
的内容而不声明新数组。所以最后,你的每个参考都指向同一个东西。
在您的代码中:
my(@row)=();
my($tempCount) = 0;
while ( @row = $qry->fetchrow_array ) {
$tempCount = scalar @row;
$logger->debug("Size of retrieved SQL Array : $tempCount");
$criteria{$row[0]} = \@row;
##@{$criteria{$row[0]} } = \@row;
}
每次while循环迭代时,都会为@row
数组赋值。但由于my(@row)=();
行发生在循环之外,@row
数组始终是相同的。因此,每次分配给数组时,您都要更改已经在所有引用中存储的内容。
要解决此问题,您需要为每次迭代声明一个新数组。最简单的方法是将声明移入while条件:
my($tempCount) = 0;
while ( my @row = $qry->fetchrow_array ) {
$tempCount = scalar @row;
$logger->debug("Size of retrieved SQL Array : $tempCount");
$criteria{$row[0]} = \@row;
##@{$criteria{$row[0]} } = \@row;
}
现在,每次参考\@row
时,您都会获得对新数组的引用。
如果您的$qry->fetchrow_array
方法返回了数组引用,则不会出现此问题:
my $row;
while ($row = $qry->fetchrow_array) {
$logger->debug("Size of retrieved SQL Array : ".@$row);
$criteria{$$row[0]} = $row; # already a reference
}
但我仍然会在我自己的代码中将其写为while (my $row = ...
,因为保持范围较小是一件好事。