1

を設定RaiseError = 1した場合、接続時または実行時にどの例外が発生しますか?

execute()メソッドを で囲むとしたらtry catch、何exceptionをキャッチする必要がありますか?

4

3 に答える 3

2

DBI ドキュメントには多くのオプションがリストされ、説明されていますが、その多くはエラー処理に関連しています。

Perl には 2 つの主要なエラー処理イディオムがあります。

  1. 偽の値を返します。エラーの理由は、いくつかのグローバル変数にあります。
  2. dieいくつかのエラー メッセージ (致命的) が表示されます。

デフォルトでは、DBI は最初のイディオムを使用します。エラーの理由は にあり$DBI::errstrます。これが機能するためには、DBI API へのすべての呼び出しの戻り値をチェックする必要があります。

怠惰な場合は、例外を使用できます。ハンドル コンストラクタで設定RaiseErrorすると、DBI メソッドは例外をスローします。ドキュメントから:

RaiseError

タイプ: ブール値、継承

このRaiseError属性を使用すると、通常の方法で単にエラー コードを返すのではなく、強制的にエラーを発生させて例外を発生させることができます。デフォルトでは「オフ」です。「on」に設定すると、エラーになるメソッドは DBI に効果的に を実行させますdie("$class $method failed: $DBI::errstr")。ここ$classで、 はドライバ クラス、$methodは失敗したメソッドの名前です。例えば、

DBD::Oracle::db prepare failed: ... error text here ...

[…]

通常、スローされた例外をキャッチするためRaiseErrorに と組み合わせて使用​​され、その後にブロックが続き、キャッチされた例外を処理します。例えば:eval { ... }if ($@) { ... }

eval {
  ...
  $sth->execute();
  ...
};
if ($@) {
  # $sth->err and $DBI::err will be true if error was from DBI
  warn $@; # print the error
  ... # do whatever you need to deal with the error
}

その eval ブロッ​​クでは、$DBI::lasthどのハンドルがエラーを引き起こしたかわからない場合に、変数が診断とレポートに役立ちます。

ご覧のとおり、Perl の例外は try/catch ではなく、eval { ... }. evalそのdies の後、$@エラー変数はそのエラーに設定され、自由に処理できます。DBI は例外オブジェクトを使用しないことに注意してください。

于 2013-07-30T14:21:10.807 に答える
2

tryとを提供する Perl Error.pm モジュールcatchは非推奨です。例外は、Perl に存在する限り、型付けされていません。例外をキャッチする方法は次のとおりです。

eval {
  do_something_which_may_throw_exception();
};
if ($@) {
  print "Exception: $@\n";
};

つまり、eval { ... }ブロックは「トライ」として機能し、ブロックif ($@) { ... }は「キャッチ」として機能し、例外テキストは特殊変数 に含まれます$@

于 2013-07-30T14:19:47.440 に答える
2

DBI から正式な例外オブジェクトを取得したい場合は、HandleError属性とException::Class::DBIを使用できます。私はそれを自分で使用します。あらすじより:

use DBI;
use Exception::Class::DBI;

my $dbh = DBI->connect($dsn, $user, $pass, {
    PrintError  => 0,
    RaiseError  => 0,
    HandleError => Exception::Class::DBI->handler,
});

eval { $dbh->do($sql) };

if (my $ex = $@) {
    print STDERR "DBI Exception:\n";
    print STDERR "  Exception Type: ", ref $ex, "\n";
    print STDERR "  Error:          ", $ex->error, "\n";
    print STDERR "  Err:            ", $ex->err, "\n";
    print STDERR "  Errstr:         ", $ex->errstr, "\n";
    print STDERR "  State:          ", $ex->state, "\n";
    print STDERR "  Return Value:   ", ($ex->retval || 'undef'), "\n";
}
于 2013-07-30T15:04:36.810 に答える