tags:

views:

1680

answers:

4

I'm running DBI in Perl and can't figure out how, when I run a prepared statement, I can figure out if the returned row count is 0.

I realize I can set a counter inside my while loop where I fetch my rows, but I was hoping there was a less ugly way to do it.

+3  A: 

Based on a quick look here, it seems that after you run

$statement->execute($arg)

you can access the row count via

$statement->rows
Harper Shelby
that's really annoying... that's exactly where I WAS looking, but totally missed it because they put that if($sth->rows == 0) AFTER the loop where they read the rows!! thanks for catching it.
Dr.Dredel
Note the very important caveat about rows in the [http://search.cpan.org/~timb/DBI-1.608/DBI.pm#rows POD].
jplindstrom
Uh, yeah, that's not how you do links apparently :)
jplindstrom
A: 

Rows definitely does vary depending on the database/driver version it seems. I would definitely look to a piece of logic there that dealt with unexpected results.

hpavc
+7  A: 

The "caveat" in the documentation (linked to in a comment on another answer) is important, and provides the real, correct answer:

Generally, you can only rely on a row count after a non-SELECT execute (for some specific operations like UPDATE and DELETE), or after fetching all the rows of a SELECT statement.

For SELECT statements, it is generally not possible to know how many rows will be returned except by fetching them all. Some drivers will return the number of rows the application has fetched so far, but others may return -1 until all rows have been fetched. So use of the rows method or $DBI::rows with SELECT statements is not recommended.

John Siracusa
so, now that we know that ->rows is not the answer to the question... what IS the answer? In the example cited above (in the answer I initially chose as correct), they are doing a select and then seeing if rows == 0... so, I'm back to being confused.
Dr.Dredel
Like the docs say, "For SELECT statements, it is generally not possible to know how many rows will be returned except by fetching them all." The key word is "generally." Some databases using some engines may behave differently. But the only way to be 100% sure in all possible cases is to fetch every row and count.
John Siracusa
+2  A: 

In order to find out how many rows are in a result set you have exactly two options:

  1. select count(*)
  2. Iterate over the result set and count the rows.

You can introduce some magic via a stored procedure that returns an array or something more fancy, but ultimately one of those two things will need to happen.

So, there is no fancypants way to get that result. You just have to count them :-)

eqbridges
The key here was my misunderstanding of what fetch does. I thought it got back a hash of some sort and just iterated over it, but, in fact, the whole thing is a stream, so, you're fetching rows right from the DB (and not from some returned object), so, the prepared execute really has no clue how many returned rows there are.
Dr.Dredel