如何在变量中存储运行time mssql错误并在perl中继续运行?

How to store the runtime mssql error in a variable and continue to run in perl?

我正在尝试将 运行time mssql 错误存储在变量中并继续处理所有其他数据。

my $sth = $dbh->prepare("exec TEST_ABC_DB.dbo.testprocedure");
$sth->execute() ;
my $db_error =$DBI::errstr; #It didn't work also I tried err and state
print "\nDB error $db_error\n";
while (@row = $sth->fetchrow_array( ) ) 
{
      print "Row: @row\n";
}

我使用了 eval 块,但它也不起作用。

我的程序如下,(示例)

CREATE procedure  testprocedure as
select 'one'
select 'three'
select 10/0
select 'five'

当我 运行 脚本显示

输出为

Row: one
DBD::ODBC::st finish failed: [unixODBC][FreeTDS][SQL Server]Divide by zero error encountered. (SQL-22012) at testing.pl line 24.
DBI::db=HASH(0xbe79a0)->disconnect invalidates 1 active statement handle (either destroy statement handles or call finish on them before disconnecting) at testing.pl line 28.

甚至 three 也不显示输出。显示唯一一个。

The PrintError handle attribute tells DBI to call the Perl warn( ) function (which typically results in errors being printed to the screen when encountered) and the RaiseError handle attribute (which tells DBI to call the Perl die( ) function upon error, typically causing the script to immediately abort). - Programming the Perl DBI

因此您可以使用下面的方法来处理这种情况。

local $SIG{__DIE__} = sub {
    my ($die_message) = @_;
    #do something..
};

I'm trying to store the error in variable

上面的代码段 $die_message 将包含错误消息。


另一种选择是将 RaiseError 设置为 0,将 PrintError 设置为 1,这样您就可以得到 warnings 但程序不会 die

PrintError

The PrintError attribute can be used to force errors to generate warnings (using warn) in addition to returning error codes in the normal way. When set "on", any method which results in an error occurring will cause the DBI to effectively do a warn("$class $method failed: $DBI::errstr") where $class is the driver class and $method is the name of the method which failed.

RaiseError

The RaiseError attribute can be used to force errors to raise exceptions rather than simply return error codes in the normal way. It is "off" by default. When set "on", any method which results in an error will cause the DBI to effectively do a die("$class $method failed: $DBI::errstr"), where $class is the driver class and $method is the name of the method that failed.

来源 - DBI docs


您也可以通过

手动完成
my $dbh=DBI->connect(....{RaiseError=>1}) or die...
my $sth=$dbh->prepare(...);
{
   local $dbh->{RaiseError} = 0;
   $sth->execute;
   if ($sth->Errstr) {
       # handle the error
   }
}
# $dbh->{RaiseError} is back to normal here

我从 回答中得到了问题的答案。

最终答案是

do
{ 
while(my @row=$sth->fetchrow_array())
{
    if ($sth->errstr) 
    {
        my $Error = $sth->errstr;   

    }
    print $row[0]."\n\n";
}
} while ($sth->{odbc_more_results});