I ran into a problem when running code similar to the following example:
my $rows = $dbh->do('UPDATE table SET deleted=NOW() WHERE id=?', undef, $id)
or die $dbh->errstr;
if (!$rows) {
# do something else
}
Since the docs state that do returns the number of rows affected, I thought that would work.
Prepare and execute a single statement. Returns the number of rows
affected orundefon error. A return value of-1means the number of
rows is not known, not applicable, or not available.
As it turns out, I was mistaken. When I debugged it, I saw that $rows in fact holds the string 0E0, which of course is a true-ish value. I dug in the docs further and saw this piece of code:
The default do method is logically similar to:
sub do { my($dbh, $statement, $attr, @bind_values) = @_; my $sth = $dbh->prepare($statement, $attr) or return undef; $sth->execute(@bind_values) or return undef; my $rows = $sth->rows; ($rows == 0) ? "0E0" : $rows; # always return true if no error }
There it is. It returns 0E0. I just don’t get why it would do that. Does anyone know?
It’s a true value, so you can distinguish it from the false value it returns on error, yet it’s numerically equal to zero (without warning), so it’s still equal to the number of records affected.
If
0was returned on success when no records are affected, you’d be forced to check errors usingdefined, which is far less convenient than testing for truth (e.g.foo() or die;).Other true zeroes. (Ignore
"0x0"; it warns.)