sunnyfedora99 has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to access the 2nd dimension of a hash I created by getting values from a MySQL DB.

Creating the Hash:

sub read_database { #my ($dir) = @_; my $sth = $sql_query{sel_ftpuser}->execute() or die "can't execute + the query"; print "CHECK_FTP: configuration seems to be OK\n"; print "CHECK_FTP: reading information from DB...\n"; my $sitedb; my $label; my $job_label; while (@site_row= $sql_query{sel_ftpuser}->fetchrow_array()) { ($label) = $site_row[2]; ($job_label) = $site_row[0]; if($label ne ""){ $sitedb->{$label}->{$job_label}->{JOB_ID} = $site_row[0]; $sitedb->{$label}->{$job_label}->{SITE} = $site_row[2]; $sitedb->{$label}->{$job_label}->{HOST} = $site_row[3]; $sitedb->{$label}->{$job_label}->{MAIL} = $site_row[6]; $sitedb->{$label}->{$job_label}->{LOCAL_DIRECTORY} = $site_ro +w[9]; $sitedb->{$label}->{$job_label}->{REMOTE_DIRECTORY} = $site_r +ow[10]; $sitedb->{$label}->{$job_label}->{PORT} = $site_row[8]; } } #print Dumper($sitedb); print "OK\n" if ($VERBOSE); return $sitedb; }

This is what the hash looks like when I use Dumper:

$VAR1 = { 'User1' => { '7' => { 'HOST' => 'foobar.baz.com', 'REMOTE_DIRECTORY' => '/tmp/user1_test +', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz@foobar.com', 'SITE' => 'user1', 'PORT' => '21' }, '2' => { 'HOST' => 'foobar.baz.com', 'REMOTE_DIRECTORY' => '/tmp/user1_test +', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz1@foobar.com', 'SITE' => 'user1', 'PORT' => '21' } }, 'User2' => { '6' => { 'HOST' => 'foobar.baz.com', 'REMOTE_DIRECTORY' => '/tmp/user2_test +', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz2@foobar.com', 'SITE' => 'user1', 'PORT' => '21' } } };

I then use a for loop to iterate through the hash

foreach my $site_name (keys %$sitedb) { print "Checking $site_name ... \n"; foreach my $subkey (keys %{$site_db{$site_name}}) { my @jobid = $site_db{$site_name}{$subkey}; print Dumper(@jobid); print "Job ID: @jobid\n"; } }

This doesn't seem to work for some reason. I can get the $site_name (first dimension) but it doesn't go any further. Am i missing something? Cheers!

Replies are listed 'Best First'.
Re: Multi-Level Hashes
by toolic (Bishop) on Sep 20, 2011 at 12:36 UTC
    Am i missing something?
    use strict and warnings

    This is probably closer to what you want:

    use warnings; use strict; use Data::Dumper; my $sitedb = { 'User1' => { '7' => { 'HOST' => 'foobar.baz.com', 'REMOTE_DIRECTORY' => '/tmp/user1_test', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz@foobar.com', 'SITE' => 'user1', 'PORT' => '21' }, '2' => { 'HOST' => 'foobar.baz.com', 'REMOTE_DIRECTORY' => '/tmp/user1_test', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz1@foobar.com', 'SITE' => 'user1', 'PORT' => '21' } }, 'User2' => { '6' => { 'HOST' => 'foobar.baz.com', 'REMOTE_DIRECTORY' => '/tmp/user2_test', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz2@foobar.com', 'SITE' => 'user1', 'PORT' => '21' } } }; foreach my $site_name ( keys %{ $sitedb } ) { print "Checking $site_name ... \n"; foreach my $subkey ( keys %{ $sitedb->{$site_name} } ) { my @jobid = $sitedb->{$site_name}{$subkey}; print Dumper(@jobid); print "Job ID: @jobid\n"; } } __END__ Checking User1 ... $VAR1 = { 'HOST' => 'foobar.baz.com', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz@foobar.com', 'PORT' => '21', 'REMOTE_DIRECTORY' => '/tmp/user1_test', 'SITE' => 'user1' }; Job ID: HASH(0x60b220) $VAR1 = { 'HOST' => 'foobar.baz.com', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz1@foobar.com', 'PORT' => '21', 'REMOTE_DIRECTORY' => '/tmp/user1_test', 'SITE' => 'user1' }; Job ID: HASH(0x661ff0) Checking User2 ... $VAR1 = { 'HOST' => 'foobar.baz.com', 'JOB_ID' => '7', 'LOCAL_DIRECTORY' => 'to-user', 'MAIL' => 'baz2@foobar.com', 'PORT' => '21', 'REMOTE_DIRECTORY' => '/tmp/user2_test', 'SITE' => 'user1' }; Job ID: HASH(0x624400)

      sunnyfedora99: Also note that the statement
          my @jobid = $sitedb->{$site_name}{$subkey};
      will never put anything other than a single element, a hash reference, into the  @jobid array, hence the content printed by the
          print "Job ID: @jobid\n";
      statement.

      Ahhh sweet... That sorted it. Cheers toolic.

Re: Multi-Level Hashes
by jwkrahn (Abbot) on Sep 20, 2011 at 12:28 UTC
    foreach my $site_name (keys %$sitedb) { print "Checking $site_name ... \n"; foreach my $subkey (keys %{$site_db{$site_name}}) { my @jobid = $site_db{$site_name}{$subkey}; print Dumper(@jobid); print "Job ID: @jobid\n"; } }

    You are using %$sitedb in the outer loop and $site_db in the inner loop.    Also, you are not dereferencing the hash keys in the inner loop.