On Dec 3, 2004, at 8:44 AM, Chad Kellerman wrote:
eval{ $dbh{'info'} = $dbh{'conn'}->prepare(qq{ SELECT User, Host from db WHERE Db = ? }) || die $DBI::errstr; $dbh{'info'}->bind_param(1, $db, SQL_VARCHAR); $dbh{'info'}->execute(); $dbh{'info'}->bind_columns(\$dbuser, \$host);
while($dbh{'info'}->fetch){ $drop{'user'} = $dbuser; $drop{'host'} = $host;
You're overwriting the hash elements $drop{'user'} and $drop{'host'}
each time you go through this loop. So you'll end up only with the last one.
}
$dbh{'info'}->finish();
No need to call finish after fetching with a loop.
};
But when I issue:
foreach $dbuser(sort keys %drop){ print "$drop{'user'} \-\> $drop{'host'}\n"; }
You're not actually using the hash key you've stored in $dbuser.
The keys in %drop will be 'user' and 'host'.
Since there are 2 keys, the loop will run twice, so the result below is expected.
I get
ckell -> localhost ckell -> localhost
You could use either an array of hashes or a hash of hashes. e.g.
while ($dbh{'info'}->fetch) {
$drop{$dbuser . $host}{'user'} = $dbuser;
$drop{$dbuser . $host}{'host'} = $host;
}...
foreach $dbuser (sort keys %drop) {
print $drop{$dbuser}{'user'}, ' -> ', $drop{$dbuser}{'host'}, "\n";
}Note that the method I used to generate the key has a fault: if you have
a dbuser 'Bob' at host 'obob', and a dbuser 'Bobo' at host 'bob', the keys
will collide, and the later values will overwrite the earlier values.
