Почему DBI делает метод return "0E0", если были затронуты нулевые строки?
У меня возникла проблема при запуске кода, подобного следующему примеру:
my $rows = $dbh->do('UPDATE table SET deleted=NOW() WHERE id=?', undef, $id)
or die $dbh->errstr;
if (!$rows) {
# do something else
}
Поскольку docs указывает, что do
возвращает количество затронутых строк, я думал, что это сработает.
Подготовьте и выполните один оператор. Возвращает количество строк или undef
при ошибке. Возвращаемое значение -1
означает количество строки неизвестны, неприменимы или недоступны.
Как оказалось, я ошибся. Когда я отлаживал его, я увидел, что $rows
фактически содержит строку 0E0
, которая, конечно же, является истинно-иш-значением. Я вырыл в документах и увидел этот фрагмент кода:
Метод по умолчанию логически похож на:
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
}
Вот оно. Он возвращает 0E0
. Я просто не понимаю, почему это так. Кто-нибудь знает?
Ответы
Ответ 1
Это истинное значение, поэтому вы можете отличить его от ложного значения, которое оно возвращает при ошибке, но оно численно равно нулю (без предупреждения), поэтому оно по-прежнему равно количеству затронутых записей.
$ perl -e'
for (undef, "0E0", 4) {
if ($_) {
printf "Success: %d rows affected\n", $_;
} else {
print "Error!\n";
}
}
'
Error!
Success: 0 rows affected
Success: 4 rows affected
Если 0
был возвращен при успешном выполнении, если не пострадали никакие записи, вам придется проверять ошибки с помощью defined
, что гораздо менее удобно, чем тестирование правды (например, foo() or die;
).
Другие истинные нули. (Игнорировать "0x0"
, он предупреждает.)