Reputation: 103
I want to pass a hash and $dbh
to my sub save2db
. However, I am getting an error message: Odd number of elements in hash assignment in file2.pm
after this line of code: my (%resultHash, $dbh) = (@_);
. Can someone please explain to me the cause of this error. Thanks in advance!
file1.pl
my $dbh_global = connect2db();
my %hash; ##Assume there are nothing wrong with the hash and it is populated
foreach my $fileName_input (@ARGV){
NVD::save2db(%hash, $dbh_global);
}
sub connect2db{
my $driver = "mysql";
my $database = "test";
my $dsn = "DBI:$driver:database=$database";
my $userid = "root";
my $password = "";
my $dbh = DBI->connect($dsn, $userid, $password) or die $DBI::errstr;
return $dbh;
}
file2.pm
sub save2db{
my (%resultHash, $dbh) = (@_); # <-Error message occured
foreach my $resultHash_entry (keys %resultHash){
my $a= $resultHash{$resultHash_entry}{'a'};
my $b= $resultHash{$resultHash_entry}{'b'};
my $c= $resultHash{$resultHash_entry}{'c'};
my $d= $resultHash{$resultHash_entry}{'d'};
my $insert_sql = $dbh -> prepare("INSERT INTO `test`.`record`
(`a`, `b`, `c`, `d`)
VALUES
(?, ?, ?, ?)");
$insert_sql->execute($a, $b, $c, $d) or die $DBI::errstr;
}
}
Upvotes: 1
Views: 2242
Reputation: 5927
Odd number of elements in hash assignment
is not an error but a warning.
The problem rises because when the values are passed to the subroutine, the values gets flattened together.
Let us consider your hash have some data for example
%hash = ("a"=>1,"b"=>2);
and $dbh_global = "abc"
Then you pass the value into the subroutine,
NVD::save2db(%hash, $dbh_global); #the problem is here.
Hash will always have a key with value. So every hash will have only even data.
you retrieve the value into the subroutine like,
my (%resultHash, $dbh) = (@_);
So %resultHash
will contain uneven values, three keys and two values like this
{
a=>1,
b=>2,
abc #This is the reason of the warning.
}
and then $dbh
has no value in it.
so Change the line as
NVD::save2db($dbh_global, %hash);
and retrieve the values into subroutine like
my ($dbh,%resultHash) = (@_);
Or else
use hash reference for to do it.
my $resulthash_ref = \%resultHash; #Hash reference
NVD::save2db($resulthash_ref, $dbh_global);
#inside the subroutine
{
my ($hash_ref,$dbh) = (@_);
my %hash = %{$hash}; #Dereference the hash
}
Upvotes: 4