tags:

views:

652

answers:

4

Hi,

I searched for this on the site already but couldn't locate anything that answered my question. Which brings me to the details:

I am querying database using a simple select query, realistically (given the scenario) it should never return more than about 5 to 6 records. I just want to check if more than one has been returned. And if more than one has been return act upon that (in an else statement) if only one has been returned then I progress with the script.


my $sql = qq { SELECT col1, col2, col3
                 FROM table
            WHERE col1 = 'foo'
          };

my $sth = $dbc->prepare_cached($sql) or die "Could not prepare statement: " . $dbc->errstr;

$sth->execute() or die "Could not execute statement: " . $sth->errstr;

# Not sure how to efficiently check for more than one row returned and still progress if true... This is my problem! I'm thinking a nested if to see if any rows were returned, and then progress with the check of one or more rows? But how can this me checked (like a count function?)
if (my $ref = $sth->fetchrow_hashref()) {

 # One row was returned...

} else {
 # More than one row was returned... Uh oh!
}

If you guys know of a thread that I couldn't locate that answers this question simply redirect my and I'll nullify this thread!

Regards, BorisTheBulletDodger!

+1  A: 

Use one of the fetchall_* or selectall_* methods (see the DBI documentation), since you'll only have 5-6 at most. Then determine how many rows you got after all.

Jonathan Leffler
+4  A: 

The only way to authoritatively determine whether more than one row has been found by a SELECT is to try to retrieve more than one row. DBI does provide the ->rows property, but it is only guaranteed to work for non-SELECT statements.

The answers to How can I check if a database query will return results? may also prove useful, even though it's not quite the same question.

Dave Sherohman
Thanks for that link Dave. As insightful as it was, this guy appears to be focusing on on getting some data or none! whereas I am focusing on getting no data or one (record), if more than one is returned then execute the 'uh oh!' section!I do think there is a limitation in DBI that doesn't provide a count feature on select statemants. Even if it is only a partial count.
+5  A: 
my $sth = $dbh->prepare();
$sth->execute();

my $row = $sth->fetchrow_hashref();
my $second = $sth->fetchrow_hashref();

if ($second) {
  print "2+ rows\n";
} elsif ($row) {
  print "1 row\n";
} else {
  print "no rows\n";
}
depesz
This was the route I was thinking of initially. I think this suffices!
Tried this, this simply reselects and populates the same row into $second as it did to $row.This currently doesn't work.
+6  A: 
my $sth = $dbh->prepare("SELECT col1, col2, col3 FROM tablename");
$sth->execute();
my $rows = $sth->fetchall_arrayref({});
if (@$rows == 0) {
    die "no rows returned";
} elsif (@$rows > 1) {
    die "too many rows returned";
}
my $row = $rows->[0];
print "col1 is $row->{col1}\n";
Chas. Owens
Thanks for this one Chas, quick question though!What would happen if no rows were returned? I am trying to log one particular error if no rows were returned, another (different) error if more than one row was returned, or else just progress with the script as only one row was returned. This just handles if there is a second row! (Still... this is a very good solution)Thanks
Hmm, point, it would die with "too many rows", let me fix that.
Chas. Owens
I am having a problem actually counting the rows here. The $rows property appears to return a "ARRAY(0x1ae2a6c)" value.I've tried numerous method to retrieve value but none appear to be successful.Thanks
Ignore the above comment. I had mistyped!Solutions works perfect.