gpt4 book ai didi

perl - DBI:在 eval 中引发错误

转载 作者:行者123 更新时间:2023-12-04 05:30:52 25 4
gpt4 key购买 nike

这个问题引用了池上的评论:

[...] But if you're going to put an eval around every statement, just use RaiseError => 0. [...]

在此thread .

如果在这种情况下将 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)返回 undef
  • (如果 RaiseError 选项设置为 1)立即退出脚本(“die”),并以退出消息形式给出错误原因。

这里的关键点是,如何处理错误取决于您。如果您愿意,您可以忽略它们,例如(以下显然仅适用于将 RaiseError 设置为 0):

for my $db ( ... ) {
my $dbh = get_database_handle( $db )
or next;
...
}

在此片段中(从您在问题中提到的@ikegami的答案复制),您循环遍历数据库连接的一些设置列表;如果某些连接给您一个 undef,您只需转至另一个连接,并且不执行任何错误操作。

不过,通常情况下,当错误发生时,您要做的不仅仅是“下一步” - 但话又说回来,您有两个选择:要么检查每个 $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');

(仅当 部分对应的“左侧部分”在 bool 上下文中计算结果为 false 时才会执行)

...或者只是将所有这些包装到 Perlish '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($@);
}

选择什么,由您决定:这是“返回语句中的错误”(除了要获取实际错误,您必须询问 $dbh 对象)和异常之间的常见决定。

但底线是你不能只写这个:

$sth = $dbh->do_something('that_can_result_in_error');
$sth->do_something('else');

...如果您确实将 RaiseError 设置为 0。在这种情况下,脚本不会消失,$sth将被分配一个undef,并且您会遇到“派生”错误(因为您无法在上调用方法>undef)。

这正是您原来问题的代码最后部分所发生的情况。

关于perl - DBI:在 eval 中引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12651154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com