次の例のようなコードを実行すると、問題が発生しました。
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
を返します。なぜそうなるのかわかりません。誰か知っている?
これは真の値であるため、エラー時に返される偽の値と区別できますが、数値的にはゼロ(警告なし)であるため、影響を受けるレコードの数と同じです。
_$ 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"
_を無視します;警告します。)