Perl DBI - 捕获错误

10

如何在Perl中捕获任何DBI错误?例如,如果插入失败,因为要插入的值中存在非法字符,我该如何避免脚本失败,而是捕获错误并适当处理它。

我不想使用"or die",因为我不想停止脚本的执行。

2个回答

14

DBI->connect中使用配置RaiseError=>1,并在调用$dbh$sth时将其包装在try块中(TryCatchTry::Tiny是try块的良好实现)。

有关其他可用连接变量的更多信息,请参见文档

例如:

use strict;
use warnings;

use DBI;
use Try::Tiny;

my $dbh = DBI->connect(
    $your_dsn_here,
    $user,
    $password,
    {
        PrintError => 0,
        PrintWarn  => 1,
        RaiseError => 1,
        AutoCommit => 1,
    }
);
try
{
    # deliberate typo in query here
    my $data = $dbh->selectall_arrayref('SOHW TABLES', {});
}
catch
{
    warn "got dbi error: $_";
};

1
你不应该也把 connect 放在 try 块中吗? - mscha
@mscha:那不是必要的 - 如果连接失败,connect将返回undef。(请参阅文档 - 您只需要检查是否返回了$ dbh。) - Ether
3
当尝试在未定义的引用($dbh)上调用方法时,会发生什么?它会崩溃,并被try/catch块捕获。在这种情况下,连接是立即建立,然后才尝试使用它,所以这很好,但在生产代码中(可能在第一个数据库查询之前很长时间连接),您可能希望做一些其他的事情。同样,在生产代码中,您可能希望对已超时的连接进行特殊处理。总之,小心阅读手册中对所调用方法的用法注意事项! - Ether

3
你还可以进行以下操作,这将允许你终止程序,或优雅地处理错误并继续执行。
$dbh = DBI->connect($data_src, $user, $pwd) or die $DBI::errstr;

my $sth = $dbh->prepare("DELETE FROM table WHERE foo = '?'");
$sth->execute('bar');
if ( $sth->err )
{
  die "DBI ERROR! : $sth->err : $sth->errstr \n";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接