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

Does anyone have a snippet that will allow me to access database information and return the field name followed by the value from the database? I am querying multiple fields and would like the field name corresponding to the value.

Replies are listed 'Best First'.
Re: parsing $sth-{NAMES}
by busunsl (Vicar) on Mar 24, 2001 at 02:43 UTC
    Check out perldoc DBI
    Look for $sth->fetchrow_hashref
    This will put every row into a hash with the column-names as keys.
Re: parsing $sth-{NAMES}
by YoungPups (Beadle) on Mar 24, 2001 at 02:49 UTC
    I assume you're talking about DBI. Once you have an executed $sth, you can use $hash_ref = $sth->fetchrow_hashref. Then $hash_ref is a hash reference with the Database's columns as keys and the values for the fetched row as values. $hash_ref will be undef after you've fetched the last row, so it's useful in a while loop.
    while ( $hash_ref = $sth->fetchrow_hashref ) { $value_1 = $hash_ref->{"COLUMN_1"}; $value_2 = $hash_ref->{"COLUMN_2"}; # Do something with values }
    I've only used DBI with Oracle, but I know that with Oracle, the column names are always in uppercase when using fetchrow_hashref. Hope that's what you were looking for...
Re: parsing $sth-{NAMES}
by Masem (Monsignor) on Mar 24, 2001 at 02:51 UTC
    If you are using the DBI interface, there is the $sth->fetchrow_hashref function which returns a hash reference with the field names as keys, and the appropriate db values as the hash values. But this is very s l o w.

    You should always try to get a subselection of the fields from the table if you can (e.g. don't use SELECT *). If you know what fields you want in array @fields, then you can set up your select statement as

    $sth->prepare( 'SELECT ' . join( ',', @fields ) . ' FROM database ETC +ETC ETC' );

    ...then use fetchrow_array as follows...

    %rowhash{ @fields } = $sth->fetchrow_array();

    (whereby you are using an hash slice to make everything neat and tidy without too much extra work). However, be aware that even this way will probably be faster than fetchrow_hashref, but still on the slow side if you have lots of data. Note that if you MUST use SELECT *, or at least, you are trying to grab all the fields, you can query via DBI all the fields for a given table, put those into @fields, and use that for further SELECTS.

    Also take a look at node Tricks with DBI, which tell you other things to avoid in this case.


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      This is close to what I am looking for. I have been expirimenting all day. The overall story is that I have an object that I will populate the properties with data from the database. I was thinking if I named the properties with the same names for the columns in the tables, I could write a loop that populated each property with corresponding database values.
        My article on www.perl.com goes into some of the techniques, especially the one Masem describes. The last example does just what you say, and it's fairly speedy too. (I haven't benchmarked it, but it uses the fastest retrieval mechanisms together.)

        Wow... I feel like a merlyn or a Dominus. *sniffle*

        The overall story is that I have an object that I will populate the properties with data from the database. I was thinking if I named the properties with the same names for the columns in the tables, I could write a loop that populated each property with corresponding database values.

        There are a number of object-relational technologies for Perl:

        1. Tangram
        2. BingoX::Carbon
        3. DBIx::Recordset
        4. Alzabo
        5. Class::DBI
        6. Class::SPOPS

        It really depends on what you want to do exactly... but the simplest thing is to use DBI as these people said and simply perlfunc:bless the hashref into the desired class.

Re: parsing $sth-{NAMES}
by lachoy (Parson) on Mar 24, 2001 at 07:13 UTC

    You can also do:

    my $sth = $dbh->prepare( 'select * from foo' ); $sth->execute; my $fieldnames = $sth->{NAME}; while ( my $row = $sth->fetch ) { for ( 0 .. ( scalar @{ $fieldnames } - 1 ) ) { print "$fieldnames->[ $_ ] is $row->[ $_ ]\n"; } }

    Also interesting is the $sth->{TYPE} arrayref. But that's not what you asked :-)

    Chris
    M-x auto-bs-mode

      This is absolutely what I was looking for. Hats off to you!