in reply to Dereferencing nested references

Here's one possible solution:
my $statement = q{ SELECT * FROM BuyersSellers WHERE FileNumber = ? }; #force selectall_arrayref to return an arrayref of hashrefs my %attr = ( dbi_fetchall_arrayref_attr => {}, ); my $BuyersSellers = $dbh->selectall_arrayref($statement, \%attr, $file +number);

The above code replaces the first prepare, execute, fetchrow_hashref block above. It does the same thing, but utilizes DBI's utility method selectall_arrayref.

Placeholders are used, which is what the question marks in the SQL query are. They allow you to substitute values into the SQL query on the fly. DBI even takes care of calling DBI->quote against each value before substituion. That means you don't have to worry about quoting values in the SQL, DBI will figure it out for you. Besides, the SQL code ends up prettier with placeholders than without =). There is an in-depth placeholder explanation here

$statement = q{ SELECT * FROM People WHERE PersonID = ? }; my $sth = $dbh->prepare($statement); foreach my $buysell (@$BuyersSellers) { $sth->execute($buysell->{PersonID}); my $row = $sth->fetchrow_hashref('NAME_lc'); $buysell->{PersonID} = { %$row }; }

Notice that I prepared the statment handle before the loop? Then inside the loop I call execute over and over, getting the matching People record, and assigning it to the $buysell->{PersonID}. Since the $sth handle was prepared using placeholders, the actual value to match PersonID doesn't need to be defined until $sth->execute, where we pass it in at run-time.

With some databases that support placeholders natively, like Oracle, the speed increases can be significant. Worst case you'll get no speed up, but just be left with a tighter loop and cleaner code.

foreach my $buysell (@$BuyersSellers) { next unless $buysell->{BuyerORSeller} eq 'BUYER'; print qq{<tr class="$class"><td>$buysell->{PersonID}->{LastName}</td +></tr>}; }

Then finally, looping through the $BuyerSellers arrayref and printing out the results

Replies are listed 'Best First'.
Re: Re: Dereferencing nested references
by ryddler (Monk) on Jan 17, 2001 at 02:44 UTC

    I was able to use part of your code, as well as some of the above info I learned to get back the data I need. My thanks to all of you.

    Now this bit below that you posted above is bothering me because I haven't been able to find any references to this attribute you set. Where did you find out how to do this litte miracle?

    #force selectall_arrayref to return an arrayref of hashrefs my %attr = ( dbi_fetchall_arrayref_attr => {}, );


    ryddler
      You really just need to look at the source for DBI, version 1.14 (I think that's when this feature was added). It's not documented, as the Todo points out:
      document dbi_fetchall_arrayref_attr attr of selectall_arrayref().
      Anyway, the way this works is that this attribute controls the behavior of selectall_arrayref. If you don't set it, it defaults to an arrayref, which tells the method to fetch the rows as array refs and return an arrayref of those arrayrefs.

      If, however, you set it to a hash ref, that tells selectall_arrayref to fetch the rows as hash refs, and return an array ref of hash refs. Make sense?