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

Dear Monks,

I have a quick question regarding how to convert data from 2 db fields into scalars.

my $Cookie1 = $cgi->cookie('C1'); my $Cookie2 = $cgi->cookie('C2'); my ($f1, $f2); if (cookie('C2')) { # found a cookie! my $sth = $dbh->prepare("SELECT field_1, field_2 FROM tablename WHE +RE field_3='?'") or "Error"; $sth->execute(cookie('C2')) or "Error"; if (my $rec = $sth->fetchrow_hashref) { $Cookie2 = cookie('C2'); $f1 = $rec->{field_1}; $f2 = $rec->{field_2};

Or do I need to repeat this for each field:

if (my $rec = $sth->fetchrow_hashref) { $Cookie2 = cookie('C2'); $f1 = $rec->{field_X};

Replies are listed 'Best First'.
Re: Database Output
by moritz (Cardinal) on Oct 11, 2010 at 15:43 UTC
    First of all you shouldn't quote the the placeholder in the SQL statement:  = ? instead of = '?'

    And you should use the RaiseError => 1 option during DBI->connect, because you seem to ignore errors from DBI, which makes debugging harder.

    You need to prepare the statement only once, but probably ->execute for each cookie value - though it's hard to understand what you actually want to achieve, because you only show non-working code, and don't verbally describe what you want to achieve in the end.

    Perl 6 - links to (nearly) everything that is Perl 6.
      Hi, Thank you, I'll fix the errors that you mentioned. I'm trying to 1) get the value of a cookie; 2) use the value to determine the db row; 3) get two fields from that row; and 4) make the value of the fields into scalars.
        1) get the value of a cookie

        Then do it once. I see three calls that are supposed to obtain the cookie value, although it's stored in a variable after the first call. <blcoqkuote>2) use the value to determine the db row;

        I believe that's what you do when fix the errors I mentioned

        3) get two fields from that row; and 4) make the value of the fields into scalars.

        Looks like the code is doing that too. What problems remain in that code?

        Perl 6 - links to (nearly) everything that is Perl 6.
Re: Database Output
by locked_user sundialsvc4 (Abbot) on Oct 11, 2010 at 16:37 UTC

    You want to call fetchrow_hashref once.   When you’ve done this, $rec now contains a hashref containing the entire row:   all of the columns mentioned in your SELECT statement are simultaneously present in it.   Each time you call it, another row is fetched, until no more rows exist, whereupon it returns undef.

    Another thought (caution: extemporaneous coding-sketch, stripped to the bone...)

    # PREPARE THE STATEMENT ONCE; USE PLACEHOLDERS my $sth = .. prepare('select ... where field3=? ...'; foreach my $cookie_name (qw/C1 C2/) { # LIST OF NAMES my $cookie_value = $cgi->cookie($cookie_name); if (defined($cookie_value)) { # FOUND A COOKIE! $sth->execute(($cookie_value)); # BIND PARAMETERS ON-THE-FLY if (my $rec = $sth->fetchrow_hashref ...

    The essential ideas here are:

    1. The query is prepared only one time.   Placeholders (un-quoted ? marks) are used to allow specific values to be bound to them.
    2. An arrayref is used in the execute call to provide values on-the-fly (left to right).   Not surprisingly (this is Perl, after all...) this is not the only way to do it...
    3. A list of cookie-names is used to avoid writing repetitive code.
    4. The cookie-value is always grabbed into a variable.   Then, the defined() function is used to check for the cookie’s existence, instead of a test for “a True value.”
    5. (It is safe to use if (my $rec ... fetchrow_hashref ... as-written, because we know that this method will either return a hashref or undef.)

Re: Database Output
by Anonymous Monk on Oct 11, 2010 at 20:37 UTC
    Hello Monks,

    I made the suggested changes and it works. Thank you.

    my $sth = $dbh->prepare ("SELECT field_1, field_2 FROM tablename WHERE + field_3=?"); $sth->execute(($Cookie1)) or "error"; foreach my $cookie_name (qw/C1 C2/) { my $cookie_value = $cgi->cookie($cookie_name); if (defined($cookie_value)) { $sth->execute(($cookie_value)); if (my $rec = $sth->fetchrow_hashref) { $f1 = $rec->{field_1}; $f2 = $rec->{field_2}; }