perl log db查询错误到日志文件中

时间:2012-07-31 23:03:13

标签: perl dbi

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

现在我正在尝试从atable中选择数据,这些数据很大并且试图根据某些条件插入到摘要表中。

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

最终我的脚本将成为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){  //将错误记录到上面的logpath中 }

2 个答案:

答案 0 :(得分: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;返回本机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默认情况下通常会被关闭。

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

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

out.log将包含常规日志,err.log将包含错误(特别是由DBI prepare() or execute()方法引发的错误)。在这种情况下,您还需要确保在printdie中使用正确的措辞,以便日志看起来很有意义。

答案 1 :(得分:1)

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

MAILTO=me@mydomain.com

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

第三,DBI有错误handler callback。您注册一个处理程序,只要错误和错误文本等句柄发生错误就会调用它。如果您从错误处理程序返回false,则DBI将像没有处理程序一样工作,然后继续死亡或发出警告。因此,与Annjawn建议的一样,设置RaiseError和创建错误处理程序更容易。

最后,如果您不想自己这样做,可以使用类似DBIx::Log4perl的内容,只需要它来记录错误而不是其他内容。任何错误都将写入您的Log4perl文件,它们包括正在执行的SQL,参数等。