I am a bit new to Perl and I need some help regarding moving my Hash of Arrays across Modules.
Currently I have a db module that stores an array like so:
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;
}
And I have a seperate perl script that reads the SQL output from the code above:
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;
}
The problem is I keep getting 0 as the retrieved array size( 2nd snippet) even though when I store the array ( in the 1st snippet ) I check and get the actual array size.
Please any help/clarification would be greatly appreciated.
EDIT
Added more code in the DB interface code.
In your
whileloop, you are assigning to@rowand then storing a reference to that array. However, each time the loop iterates, you are replacing the contents of@rowwithout declaring a new array. So at the end, each of your references point towards the same thing.In your code here:
Each time the while loop iterates, you assign new values to the
@rowarray. But since themy(@row)=();line occurs outside of the loop, the@rowarray is always the same. So each time you assign to the array, you are changing what is stored in all of the references you have already taken.To fix the problem, you need to declare a new array for each iteration. The simplest way to do this is to move the declaration into the while condition:
Now each time you take the reference
\@rowyou will be getting a reference to a new array.If your
$qry->fetchrow_arraymethod returned an array reference, you would not have had the issue:But I would still write that as
while (my $row = ...in my own code, since keeping scopes small is a good thing.