문제

이 질문에는 이견에서 깨끗:

[...] 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)return undef
  • (는 경우 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).

과에서 정확히 무슨 일이 있었는지 마지막 부분의 코드에서는 원래 질문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top