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

Dear all: I was trying to read some values in a Access tables into an array. I was succeeded in printing out these values. But I could not keep these values in the array. I mean when I was trying to use this array later, it seemed empty. Part of the code I use is like this,
$dbh = DBI->connect('dbi:ODBC:Alex') || die "Error opening DB: $DBI::e +rrstr\n"; $sth = $dbh->prepare("SELECT Inumber FROM plana"); $sth->execute() or die "Couldn't execute query: $DBI::errstr\n"; while (my @row1 = $sth ->fetchrow_array){ print "@row1\n"; #All the elements were printed out by this state +ment. @IDnumber=@row1; } print "@row1\n"; print "@IDnumber\n";
Nothing was printed out for @row1 by "print "@row1\n". In @IDnumber, only the last element of @row1 was printed out. would you please help me to figure this out? Thank you very much in advance. Young

Replies are listed 'Best First'.
Re: How can I keep the values in the array?
by Limbic~Region (Chancellor) on Mar 03, 2004 at 17:48 UTC
    Young,
    It sounds like your issue is understanding scoping. Check out Coping with Scoping for more information. What you need to do is push your individual rows on to an array that can be seen both inside and outside the scope of the while block.
    my @bucket; while ( my @row = $sth ->fetchrow_array ) { print "@row\n"; push @bucket , \@row; } print "The count of the first row is :" , scalar @{ $bucket[0] }, "\n" +; print "The first row is : @{$bucket[0]}\n"; # or for all the rows you saw for my $row ( @bucket ) { print "The count in this row is :", scalar @$row, "\n"; print "The row is @$row\n"; }

    Cheers - L~R

Re: How can I keep the values in the array?
by halley (Prior) on Mar 03, 2004 at 17:45 UTC
    You said something like:
    while (my @foo = ...) { ... }
    Any variable you declare with my @foo here will disappear at the end of the loop.

    Instead, phrase it like:

    my @foo; while (@foo = ...) { ... }
    If you had use strict; Perl would have complained on your final lines because the variables wouldn't exist at that time.

    --
    [ e d @ h a l l e y . c c ]

      halley,
      It might also be worth mentioning that just changing the scope of the variable may not lead to the desired results. Each iteration the array is going to get overwritten. If what was desired was the only to remember the first row (as @row1 would indicate) then additional modifications would have to be made such as this.

      Cheers - L~R

      Hi thank you for your reply. But I coded the way your show me, the array was still empty after the loop.
Re: How can I keep the values in the array?
by blue_cowdawg (Monsignor) on Mar 03, 2004 at 17:51 UTC

        Nothing was printed out for @row1 by "print "@row1\n". In @IDnumber, only the last element of @row1 was printed out.

    Sounds like normal behavior to me. When you are looping through you are overwriting @row1 with every iteration. In the last iteration you are overwriting it with an empty array. the variable falls out of scope and is therefore undefined. If you had use strict; turned on you might have caught that.

    Here's some mods for ya!

    my @IDnumber=(); #Initialize this... while (my @row1 = $sth ->fetchrow_array){ push @IDnumber,[@row1]; # save the row as an anon-array print "@row1\n"; #All the elements were printed out by this state +ment. @IDnumber=@row1; } print "@row1\n"; #this is going to be empty! # snip! print "@IDnumber\n"; foreach my $row(@IDnumber){ printf "%s\n",join(",",@$row); }
    Try it.. you'll like it....

    UPDATED: Didn't catch the scoping the first time through... Thanks Limbic~Region for watching my back!


    Peter L. Berghold -- Unix Professional
    Peter at Berghold dot Net
       Dog trainer, dog agility exhibitor, brewer of fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and a good Belgian ale in your chalice.
Re: How can I keep the values in the array?
by Tomte (Priest) on Mar 03, 2004 at 17:51 UTC

    First guess at a quick glance: This is a scoping problem, try

    #---- snip --- my @allrows; my @UDNumber; while (my @row1 = $sth ->fetchrow_array){ print "@row1\n"; # prints the current row @allrows = (@allrows,@row1); @IDnumber=@row1; } # allrows contains everything now # IDNumber contains the last row
    @row1 in your code is only valid inside the loop-body, always use strict; and use warnings to fight scoping errors and "code better(tm)" ;-)

    regards,
    tomte


    Hlade's Law:

    If you have a difficult task, give it to a lazy person --
    they will find an easier way to do it.

      Thank you so much! It works!!! Young

        It may work, but it also copies the @allrows array again and again for each loop iteration. This is probably a Bad Thing (tm). I would suggest using push to add new items to the end of an existing array. I would also suggest checking out Limbic~Region's reply. His code actually creates an array of arrays, which may preserve the original structure of the data more accurately.

Re: How can I keep the values in the array?
by jao (Acolyte) on Mar 04, 2004 at 11:22 UTC
    Forgive me if i'm wrong, but I think everybody missed a little thing that could help you the next time:

    When you do:
    @IDnumber=@row1;
    inside a loop.

    The value of @IDnumber will ALWAYS be the last item of the loop.

    So what you need to do, is to ADD an item to @IDnumber, or %IDnumber (using push array,var; should work fine).

    my 2 cents

    Best regards,

    - jao
    web developer
    http://dev.geekadelic.com
Re: How can I keep the values in the array?
by arden (Curate) on Mar 03, 2004 at 17:45 UTC
    I believe your context is only within the scope of the while loop. Try declaring  my @row1; before the while loop, then just using  while ( @row1 = ...

    - - arden.