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

Hi Monks!
I am working on this code and on these lines I cant figured it out what is going on there. Could someone help me understand or if there is a better way of doing these simple checks.
One issue I have is that I am trying to get the username from the DB and it is coming back empty when there is a value for the username in the DB. What I am doing wrong here?
... my %info = (); my $hashref = (); my $dbh = connectstuffhere->connect_mysql(); # this its all set, conne +ction works, not the issue here my $sth = $dbh->prepare("select * from mytable where lastn = ? and use +rname = ? ") or &die("Can't select: ",$dbh->errmsg); $sth->execute($lname,$username); $hashref = $sth->fetchrow_hashref; %info = {$hashref}; if (!(scalar %info)) { # what does this mean? &dead("Username '$username' is not here."); } if ($info{username} eq "") { # but there is a username value in the da +tabase and the field its called username &dead("No username found!"); } ...

Thanks for the Help!

Replies are listed 'Best First'.
Re: Help on fetchrow_hashref!
by kennethk (Abbot) on Nov 09, 2010 at 16:31 UTC
    One problem is your assignment %info = {$hashref};. You are assigning an improperly formatted hash reference containing a hash reference to a hash. Were you using warnings, it would have told you this. See Use strict warnings and diagnostics or die. What you likely mean is %info = %{$hashref};. This dereferences the hashref returned by fetchrow_hashref and then stores it in %info. See perlreftut.

    I would strongly suggest adding some additional tests to your routine. For example, if your placeholder binding fails (implicitly performed in your execute), your script will continue on since your don't check if your execute was successful. For example, I would suggest changing $sth->execute($lname,$username); to $sth->execute($lname,$username) or die "Execute failed: ", $dbh->errmsg; As well, to test if the row existed after a successful query, how about

    if (my $hashref = $sth->fetchrow_hashref) { %info = %{$hashref}; } else { die "lname, username combo did not match any records"; }

    Update: Typo fixed, thanks wfsp.

      Is there a way to avoid the usual "Software Error" message and redirect the errors from ""die to a customized error message so the user cant see information that doesn't matter for them?

        Yes. Don't call die but store the message somewhere and then call exit.

Re: Help on fetchrow_hashref!
by zentara (Cardinal) on Nov 09, 2010 at 16:29 UTC
    Not much of a db expert, but I do see a possible explanation for empty results.

    Possibly try putting a % sign in front of the {}

    %info = %{$hashref};

    (!(scalar %info)) { # what does this mean?

    Running scalar on the hash, returns the number of keys the hash has, so it's checking for an empty list.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Help on fetchrow_hashref!
by Tux (Canon) on Nov 09, 2010 at 17:00 UTC

    Or use bind_columns ...

    my %info; my $sth = $dbh->prepare ("select * from mytable where lastn = ? and us +ername = ? ") or die "Can't select: ", $dbh->errmsg; $sth->execute ($lname, $username); $sth->bind_columns (\@info{@{$sth->{NAME_lc}}}); if ($sth->fetch) { print "Username: $info{username}\n"; : }

    Enjoy, Have FUN! H.Merijn