
perl+DBI プログラムの鉄則 のつつき。
鉄則その2.
DB に接続したらすぐに別の関数に飛ばし、そこですべての処理を行う。
main 部分は
my $dbh = DBI->connect(...) || die "$!";
eval {
...
$dbh->commit;
$dbh->disconnect;
};
if ( $@ ){
$dbh->rollback;
$dbh->disconnect;
}
とだけ書いておく。これは Java で言うところの try ~ catch に相当する。
内部で die すれば if ( $@ ) で引っかかるわけだ。なお、RaiseError を
ON にしておかないと、エラーが起こっても自動では die してくれないので
注意。disconnect の部分には、エラーが発生したことをログに記録するなどの
後始末を処理を付け加えること。
try ~ catch は何段階でもネストできるのと同様、
eval { ... }; if ( $@ ){ ... }
もネストできる。
一部の処理でエラーを無視したい場合がある。例えば INSERT の際に一意制約が
発生しても処理を続行したい場合は、
my $sql =
"INSERT INTO table2 ( ".
" col1, ".
" col2 ".
") VALUES (".
" ?. ".
" ? ".
")";
eval {
my $sth = $dbh->prepare($sql);
$sth->bind_param(1, $col1_value);
$sth->bind_param(2, $col2_value);
};
if ( $@ ){
if ( DBI::errstr !~ m/ORA-00001/ ){
print "一意制約が発生したけど続行します。\n";
} else {
die "$@";
}
}
などとする (ORA-00001 ってのは Oracle の場合)。一意制約ではなかった場合、
再度 die しているのがポイント。この die は、上位の eval (サンプルの
プログラムでは main 部分の eval) があれば、そこで引っかかってくれる。
鉄則その2.
DB に接続したらすぐに別の関数に飛ばし、そこですべての処理を行う。
main 部分は
my $dbh = DBI->connect(...) || die "$!";
eval {
...
$dbh->commit;
$dbh->disconnect;
};
if ( $@ ){
$dbh->rollback;
$dbh->disconnect;
}
とだけ書いておく。これは Java で言うところの try ~ catch に相当する。
内部で die すれば if ( $@ ) で引っかかるわけだ。なお、RaiseError を
ON にしておかないと、エラーが起こっても自動では die してくれないので
注意。disconnect の部分には、エラーが発生したことをログに記録するなどの
後始末を処理を付け加えること。
try ~ catch は何段階でもネストできるのと同様、
eval { ... }; if ( $@ ){ ... }
もネストできる。
一部の処理でエラーを無視したい場合がある。例えば INSERT の際に一意制約が
発生しても処理を続行したい場合は、
my $sql =
"INSERT INTO table2 ( ".
" col1, ".
" col2 ".
") VALUES (".
" ?. ".
" ? ".
")";
eval {
my $sth = $dbh->prepare($sql);
$sth->bind_param(1, $col1_value);
$sth->bind_param(2, $col2_value);
};
if ( $@ ){
if ( DBI::errstr !~ m/ORA-00001/ ){
print "一意制約が発生したけど続行します。\n";
} else {
die "$@";
}
}
などとする (ORA-00001 ってのは Oracle の場合)。一意制約ではなかった場合、
再度 die しているのがポイント。この die は、上位の eval (サンプルの
プログラムでは main 部分の eval) があれば、そこで引っかかってくれる。
スポンサーサイト


