所以我开始熟悉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中 }
答案 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()
方法调用执行上述基本异常处理。请注意,默认情况下,DBI
将AutoCommit
设置为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()
方法引发的错误)。在这种情况下,您还需要确保在print
或die
中使用正确的措辞,以便日志看起来很有意义。
答案 1 :(得分:1)
首先,请记住,如果您将电子邮件地址放在crontab文件的顶部,那么cron作业的任何输出都将通过电子邮件发送给您:
MAILTO=me@mydomain.com
其次,如果在连接时将DBI的RaiseError设置为1,则无需检查每个调用,只要有人发生,DBI就会引发错误。
第三,DBI有错误handler callback。您注册一个处理程序,只要错误和错误文本等句柄发生错误就会调用它。如果您从错误处理程序返回false,则DBI将像没有处理程序一样工作,然后继续死亡或发出警告。因此,与Annjawn建议的一样,设置RaiseError和创建错误处理程序更容易。
最后,如果您不想自己这样做,可以使用类似DBIx::Log4perl的内容,只需要它来记录错误而不是其他内容。任何错误都将写入您的Log4perl文件,它们包括正在执行的SQL,参数等。