22

次の例のようなコードを実行すると、問題が発生しました。

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

影響を受けた行数を返すドキュメントの状態なので、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。なぜそんなことをするのか、私にはわかりません。誰か知っていますか?

4

1 に答える 1

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

影響を受けるレコードがなく、成功時に が返された場合0、 を使用してエラーをチェックする必要がありますdefined。これは、真実をテストするよりもはるかに不便です (例: foo() or die;)。

その他の真のゼロ。(無視"0x0"します。警告します。)

于 2012-11-13T10:10:12.057 に答える