如果零行受到影响,为什么DBI的do方法返回“0E0”?

时间:2012-11-13 10:08:15

标签: perl dbi

运行类似以下示例的代码时遇到了问题:

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,这当然是一个真正的值。我进一步挖掘了文档并看到了这段代码:

  

默认的do方法在逻辑上类似于:

  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 个答案:

答案 0 :(得分:27)

这是一个真值,所以你可以将它与错误时返回的假值区分开来,但它在数值上等于零(没有警告),所以它仍然等于受影响的记录数。

$ 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; )。

Other true zeroes。 (忽略"0x0";它警告。)