1

それで私はPerlに慣れ始め、最初のDbスクリプトを書きました。

今、私は巨大なatableからデータを選択し、いくつかの基準に基づいて要約テーブルに挿入しようとしています。

タイムアウトやその他のデータベースの問題が原因で、selectクエリが失敗したり、insertクエリが失敗したりする可能性があります。

最終的に、私のスクリプトは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;また、ネイティブの Oracle エラー コードを返す which を使用して、エラーをトラップし、それに応じて終了することもできます。

上記の基本的な例外処理はexecute()、スクリプト内のすべてのメソッド呼び出しに対して実行できます。明示的に無効にしない限り、デフォルトで (有効) に設定されDBIていることに注意してください。したがって、トランザクションは挿入ごとに自動コミットされます。トランザクション全体を処理するために、自動コミットを無効にして、コミットするときに使用して処理するか、カスタムを使用することができます(より大きなデータセットの場合)。AutoCommit1ATOMICITY$dbh->commit$dbh->rollbackcommit point

または、DBへの接続中に以下を使用できます

$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 とは、シェル cron ジョブから呼び出すことを意味します。その場合、cron 自体からの perl スクリプトへの呼び出しは、以下のようなログ ファイルにリダイレクトできます。

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

out.log通常のログerr.logが含まれ、エラーが含まれます (具体的には DBIprepare() or execute()メソッドによってもスローされます)。この場合、ログが意味のあるものに見えるように、 printorで適切な言い回しを使用していることを確認する必要もあります。die

于 2012-08-01T00:44:20.377 に答える
1

まず、crontab ファイルの先頭に電子メール アドレスを入力すると、cron ジョブからの出力がすべて電子メールで送信されることに注意してください。

MAILTO=me@mydomain.com

次に、接続時に DBI のRaiseErrorを 1 に設定すると、すべての呼び出しをチェックする必要がなくなり、DBI はエラーが発生するたびにエラーを発生させます。

第三に、DBI にはエラーハンドラ callbackがあります。ハンドラーを登録すると、エラーやエラー テキストなどのハンドルでエラーが発生するたびに、ハンドラーが呼び出されます。エラー ハンドラーから false を返すと、DBI はハンドラーがない場合と同様に動作し、停止または警告に進みます。その結果、RaiseError を設定してエラー ハンドラを作成する方が、Annjawn が提案したよりも簡単です。

最後に、これを自分で行いたくない場合は、DBIx::Log4perlのようなものを使用して、単にエラーのみを記録するように要求することができます。エラーは Log4perl ファイルに書き込まれ、実行中の SQL やパラメータなどが含まれます。

于 2012-08-01T07:37:19.863 に答える