DBI:raiseerror 에 eval
-
11-12-2019 - |
문제
이 질문에는 이견에서 깨끗:
[...] But if you're going to put an eval around every statement, just use RaiseError => 0. [...]
이 스레드.
내가 무엇을 얻는 경우에,내가 설정 RaiseError
하기 0
이러한 상황에서는?
#!/usr/bin/env perl
use warnings;
use 5.10.1;
use DBI;
my $db = 'my_test_sqlite_db.sqlite';
open my $fh, '>', $db or die $!;
close $fh or die $!;
my ( $dbh, $sth );
eval {
$dbh = DBI->connect( "DBI:SQLite:dbname=$db", "", "", {} );
};
if ( $@ ) { print $@ };
my $table = 'my_sqlite_table';
say "RaiseError = 1";
say "PrintError = 0";
$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 0;
eval {
$sth = $dbh->prepare( "SELECT * FROM $table" );
$sth->execute();
};
if ( $@ ) { print "ERROR: $@" };
say "\nRaiseError = 0";
say "PrintError = 1";
$dbh->{RaiseError} = 0;
$dbh->{PrintError} = 1;
eval {
$sth = $dbh->prepare( "SELECT * FROM $table" );
$sth->execute();
};
if ( $@ ) { print "ERROR: $@" };
say "\nRaiseError = 0";
say "PrintError = 0";
$dbh->{RaiseError} = 0;
$dbh->{PrintError} = 0;
eval {
$sth = $dbh->prepare( "SELECT * FROM $table" );
$sth->execute();
};
if ( $@ ) { print "ERROR: $@" };
출력:
RaiseError = 1
PrintError = 0
ERROR: DBD::SQLite::db prepare failed: no such table: my_sqlite_table at ./perl2.pl line 23.
RaiseError = 0
PrintError = 1
DBD::SQLite::db prepare failed: no such table: my_sqlite_table at ./perl2.pl line 33.
ERROR: Can't call method "execute" on an undefined value at ./perl2.pl line 34.
RaiseError = 0
PrintError = 0
ERROR: Can't call method "execute" on an undefined value at ./perl2.pl line 44.
해결책
실패하면 몇 가지 이유로,가장$dbh 방법은 다음 중 하나입니다.
- (는 경우
RaiseError
옵션을 설정 0)returnundef
- (는 경우
RaiseError
옵션을 설정 1)즉시 종료한 스크립트가('죽')오류 이유로 주어진 종료 메시지입니다.
여기에서 중요한 점은 그것이 당신이 어떻게정에 오류가 있습니다.당신이 원하는 경우에,그냥 무시할 수 있습니다 예를 들어,(다음과 같은 분명히 작업 RaiseError
설정 0
만):
for my $db ( ... ) {
my $dbh = get_database_handle( $db )
or next;
...
}
이 조각(복사에서@케가미의 대답은 당신이 언급했듯이 귀하의 질문에)당신 루프를 통해 일부의 목록을 설정한 DB 연결는 경우 몇 가지 연결을 제공 undef
, 가지로,당신은 또 다른 하나,그리고 아무것도 하지 않 오류가 있습니다.
일반적으로,하지만,당신은 당신보다 더 많은 일을 그냥'nexting 때'오류가 발생하면,두 가지 중에서 선택할 수 있습니다.거나 확인 각 $dbh
-관련 문과 함께 무언가 이것을 좋아한다:
$sth = $dbh->prepare('some_params')
or process_db_error('In prepare');
...
$res = $sth->execute('another_set_of_params')
or process_db_error('In execute');
...
$res->doAnythingElse('something completely different')
or process_db_error('In something completely different');
(로 or
부품이 수행될 경우에만 해당하는'왼쪽 부분에'평가 false
에 Boolean 컨텍스트).
...또는 포장이 반경험'try-catch'block:
if (!eval {
$sth = $dbh->prepare('some_params');
...
$res = $sth->execute('another_set_of_params');
...
$res->doSomethingElse('something completely different')
...
1 # No exception
}) {
process_db_error($@);
}
What's 를 선택,그것은 당신이:그것은 일반적인 결정을 사'오류를 반환에서 계산서'(제외하고는 가 실제 오류를 요청하$dbh 개체)만,예외가 있습니다.
지만 결론은 쓸 수 없습니다만 이것:
$sth = $dbh->do_something('that_can_result_in_error');
$sth->do_something('else');
...았다면 설정 RaiseError
하기 0
.이 경우 스크립트가 죽지 않는다, $sth
이 할당됩니다 undef
, 고,당신은 자신에게'유도체'오류(으로 호출할 수 없는 방법에 대 undef
).
과에서 정확히 무슨 일이 있었는지 마지막 부분의 코드에서는 원래 질문입니다.