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

I would like to put the info in the rhic_au_fy01_fill[$dbEvents->ct_sql("use rhic_au_fy01_fill")] in a hash to speed up this program. I've looke at many perlfaq's, but I'm still having trouble doing correctly...
#! /usr/local/bin/perl -w # A perl program to analyze the notifAlarmLog Table and quench times use FileHandle; use IPC::Open2; use Symbol; # use Tk; use Sybase::CTlib; use Time::Local; use strict; my(%systemNames); systemNames(); # fill in the hash of PS sytem names use strict; my $dbAlarms = new Sybase::CTlib 'harmless','harmless','OPSYB1','notif +LogTable'; $dbAlarms->ct_sql("use TomTest"); my $sql = "SELECT distinct name FROM notifAlarmLog"; my(@rows,$row); @rows = $dbAlarms->ct_sql($sql); foreach $row (@rows) { $sql = "SELECT * FROM notifAlarmLog WHERE name like '$row->[0]'"; my($supply,@supplies); @supplies = $dbAlarms->ct_sql($sql); # count all alarms for each PS my $count = @supplies; # count how many alarms are 2 seconds or less for each PS? my $OneSecCount = 0; # count how many alarms are >2 and <=10 seconds for each PS? my $TwoSecCount = 0; # count how many alarms are >10 seconds for each PS ? my $TenSecCount = 0; # count how many alarms occur w/in 10 seconds after a QUENCH EVENT? my $QuenchCount = 0; foreach $supply (@supplies) { $OneSecCount++ if(($supply->[4]-$supply->[3]) <= 2); $TwoSecCount++ if(($supply->[4]-$supply->[3]) > 2 and ($supply->[ +4]-$supply->[3]) <= 10); $TenSecCount++ if(($supply->[4]-$supply->[3]) > 10); my $dbEvents = new Sybase::CTlib 'harmless','harmless','OPSYB1','f +illeventsT'; $dbEvents->ct_sql("use rhic_au_fy01_fill"); my $sql = "SELECT * FROM fillEventsT WHERE rhicTime like 'Oct%' and (event like 'ev-bquench' + or event like 'ev-yquench')"; my(@fills,$fill); @fills = $dbEvents->ct_sql($sql); foreach $fill (@fills) { # how many alarms occur w/in 10 seconds a +fter a QUENCH EVENT? # to change time of filter, change time here!!! $QuenchCount++ if(($supply->[3] - $fill->[0]) <= 10) and (($supp +ly->[3] - $fill->[0]) > 0); } } #filter out alarms that occur w/in 10 seconds after a Quench EVENT my $diff = $count - $QuenchCount; my ($f1,$adoName,$f3) = split(":",$row->[0]); my $SiteWideName = $main::systemNames{$adoName} . ":$f3"; # print ":$adoName: :$SiteWideName: \n"; print "$SiteWideName , $count , $OneSecCount , $TwoSecCount , $TenSe +cCount, $diff \n"; } sub systemNames { # fill in the systenName hash use strict; my $dbAdo = new Sybase::CTlib 'harmless','harmless','OPSYB1','notifL +ogTable'; $dbAdo->ct_sql("use serverAdo"); my $sql = "SELECT name,systemName from adoInst where name like 'psWa +tch%'"; my(@rows,$row); @rows = $dbAdo->ct_sql($sql); foreach $row (@rows) { $main::systemNames{$row->[0]} = $row->[1]; # print "<$row->[0]> <$row->[1]> \n"; } }

Replies are listed 'Best First'.
Re: creating a table hash
by djantzen (Priest) on Aug 08, 2002 at 18:29 UTC

    First of all, a helpful hint about posting successfully: narrow down the problem you're having as tightly as possible. Demonstrate the trouble and explain the results of your attempts as succinctly as you can, and please provide references to helpful material, such as this article. According to the documentation, your call to ct_sql will return an array of references to rows, perhaps something like this:

    my @array = ([1,2], [3,4], [5,6]);
    So it seems like your implementation in systemNames should work:
    @rows = $dbAdo->ct_sql($sql); foreach $row (@rows) { $main::systemNames{$row->[0]} = $row->[1]; }
    What (wrong) behavior are you seeing when you do this?

    Once you've got that working with a foreach loop, you might try map for a nicer solution:

    my %hash = map { $$_[0] => $$_[1] } @array;
    Where map runs through each element of @array, setting $_ each iteration to the current element (an array reference), which you can then dereference and pull apart before inserting the results into a hash.