fc2ブログ

無精で短気で傲慢なプログラマ

UNIX や web やプログラムの技術的なことを中心に。

perl+DBI プログラムの鉄則 - eval で例外処理

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) があれば、そこで引っかかってくれる。
スポンサーサイト



PageTop

コメント


管理者にだけ表示を許可する