1

所以我开始熟悉 Perl 并编写了我的第一个 Db 脚本。

现在我正在尝试从巨大的表中选择数据,并尝试根据某些标准插入汇总表。

现在有机会,选择查询可能会失败,或者插入查询可能由于超时或其他我无法控制的数据库问题而失败。

最终我的脚本将成为 cron 脚本。

我可以只记录我遇到的连接错误,插入并选择到脚本中生成的文件吗?

$logfile = $path.'logs/$currdate.log';

这是我的代码:

my $SQL_handled="SELECT  division_id,region_id, NVL(COUNT(*),0) FROM super_tab GROUP BY division_id,region_id;";
my $result_handled = $dbh->prepare($SQL_handled);
$result_handled->execute();
while (my ($division_id,$region_id,$count ) = $result_handled->fetchrow_array()){
    my $InsertHandled="INSERT INTO summary_tab (date_hour, division_id, region_id,volume) VALUES ('$current',$division_id,$region_id,$market_id,'$service_type','$handled',$count);";
    my $result_insert_handled = $dbh->prepare($InsertHandled);

    $result_insert_handled->execute();

}

就像是

if(DBI-query failed ) { // 将错误记录到上述日志路径 }

4

2 回答 2

2

它通常是这样完成的

my $SQL_handled="SELECT  division_id,region_id, NVL(COUNT(*),0) FROM super_tab GROUP BY division_id,region_id;";
my $result_handled = $dbh->prepare($SQL_handled);
my $retval = $result_handled->execute();
if(!$retval){
    #open a log file and write errors 
    writelog();
    die "Error executing SQL SELECT - $dbh->errstr";
}
while(my ($division_id,$region_id,$count ) = $result_handled->fetchrow_array()){....
 }

---------------------------------

sub writelog{
   my $path = "/path/to/logfile";
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
   $year += 1900; 
   $mon++;
   my $currdate = "$mon$mday$year";

   $logfile = $path . "/$currdate.log";
   open (OUT, ">>$logfile");
   print OUT "There was an error encountered while executing SQL- $dbh->errstr \n";
   close(OUT);
}

您还可以使用$dbh->err;which 返回本机 Oracle 错误代码来捕获错误并相应地退出。

可以对execute()脚本中的每个方法调用执行上述基本异常处理。请记住,默认情况下DBIAutoCommit设置为1(启用),除非明确禁用。因此,您的事务将在每次插入时自动提交,为了处理ATOMICITY整个事务,您可以禁用自动提交并在您想要提交时使用$dbh->commit$dbh->rollback处理,或者可能使用一些自定义commit point(对于更大的数据集)。

或者可以在连接到数据库时使用以下内容

$dbh = DBI->connect( "dbi:Oracle:abcdef", "username", "password" , {
  PrintError => 0,   ### Don't report errors via warn(  )
  RaiseError => 1    ### Do report errors via die(  )
} );

这将通过自动报告所有错误die。默认情况下RaiseError通常是关闭的。

另外,如果我对您的理解正确,那么 cron 您的意思是您将从 shell cron 作业中调用它。在这种情况下,从 cron 本身调用 perl 脚本可以重定向到日志文件,如下所示

perl your_perl.pl >> out.log 2>> err.log

out.log将包含常规日志err.log并将包含错误(特别是由 DBIprepare() or execute()方法抛出)。在这种情况下,您还需要确保使用适当的措辞printdie使日志看起来有意义。

于 2012-08-01T00:44:20.377 回答
1

首先,请记住,如果您将电子邮件地址放在 crontab 文件的顶部,则 cron 作业的任何输出都将通过电子邮件发送给您:

MAILTO=me@mydomain.com

其次,如果您在连接时将 DBI 的RaiseError设置为 1,则无需检查每个调用,每当发生错误时,DBI 都会引发错误。

第三,DBI 有一个错误处理回调。您注册一个处理程序,并且每当错误和错误文本等中的句柄发生错误时都会调用它。如果您从错误处理程序返回 false,DBI 将像没有处理程序一样工作并继续死亡或发出警告。因此,设置 RaiseError 和创建错误处理程序比 Annjawn 建议的要容易。

最后,如果您不想自己执行此操作,您可以使用DBIx::Log4perl 之类的东西,只需要求它记录错误即可。任何错误都将写入您的 Log4perl 文件,其中包括正在执行的 SQL、参数等。

于 2012-08-01T07:37:19.863 回答