Почему DBI делает метод return "0E0", если были затронуты нулевые строки? - программирование
Подтвердить что ты не робот

Почему 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. Я просто не понимаю, почему это так. Кто-нибудь знает?

4b9b3361

Ответ 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", он предупреждает.)