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

sim*_*que 19 perl dbi

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

my $rows = $dbh->do('UPDATE table SET deleted=NOW() WHERE id=?', undef, $id) 
  or die $dbh->errstr;
if (!$rows) {
  # do something else
}
Run Code Online (Sandbox Code Playgroud)

由于文档声明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
  }
Run Code Online (Sandbox Code Playgroud)

它就是.它回来了0E0.我只是不明白为什么会这样做.有人知道吗?

ike*_*ami 28

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

$ 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
Run Code Online (Sandbox Code Playgroud)

如果0在没有记录受到影响的情况下成功返回,则会被迫检查错误defined,这比测试真实要便宜得多(例如foo() or die;).

其他真正的零.(忽略"0x0";警告.)

  • 两者都可以,但是`$ rows == 0`会更精神. (2认同)
  • @mvp,从技术上讲,"0但是真实的"是唯一一个特殊编码的案例,但有[十几种方式](http://www.perlmonks.org/?node_id=464548)实现这一点.(该页面上的"0x0"是错误的;它警告.) (2认同)