perl dbi从哪里获取其错误字符串,是否可以修改它以提供更多有用的信息?

时间:2013-07-30 14:04:57

标签: perl dbi

我正在开发一个项目,我正在读取日志文件并处理它们并将它们加载到Postgres数据库中。这些日志文件按月分隔,这意味着我给我的脚本一个特定的月份,它遍历目录(实际上它们是每个服务器的目录,有8个服务器)并抓取文件并上传它们。这段代码将它们加载到数据库中:

sub insert_n_gridftp_usage {
eval {
    $sth = $dbh->prepare("INSERT into $stats_table VALUES ($epoch, '$servername', $currentnumhash{'RETR'}, $currentbyteshash{'RETR'}, $currentnumhash{'STOR'}, $currentbyteshash{'STOR'}, $currentnumhash{'ERET'}, $currentbyteshash{'ERET'}, $currentnumhash{'ESTO'}, $currentbyteshash{'ESTO'}, $currentnumhash{'LIST'}, $currentbyteshash{'LIST'}, $currentnumhash{'NLST'}, $currentbyteshash{'NLST'}, $currentnumhash{'MLSD'}, $currentbyteshash{'MLSD'}, $currentnum, $currentbytes);") || die; 
    $sth->execute;
    $dbh->commit;
} or
do {
    $stats_fails++;
    eval { $dbh->rollback };
}   

}

该表具有唯一的索引约束,可以防止加载重复记录。现在当这个语句遇到重复时,我在stderr上得到了这个错误:

DBD::Pg::st execute failed: ERROR:  duplicate key value violates unique constraint "transfer_unique"DETAIL:  Key (starttime, endtime, file)=(1366822840, 1366822840, /dev/null) already exists. at ./database_load_script.pl line 196, <LOGFILE> line 1332302.

LOGFILE是我的变量,字线后面的数字是我的变量$ linenum。我没有在我的代码中的任何地方设置此错误字符串。那么,这个字符串来自哪里?是否可以修改此字符串以指出其读取的文件? (我有一个文件名变量)。任何帮助表示赞赏。

感谢。

1 个答案:

答案 0 :(得分:2)

您确实可以在查询失败时修改输出内容。目前你在做:

$sth = $dbh->prepare("...") || die;

这意味着die正在使用其默认参数$!的值。但是,您也可以将自定义字符串传递给die,它会在标准错误上输出该字符串;该字符串,如果是双引号,可以像其他任何内容一样插入变量。关于die参数的另一个要点是它们是神奇的,因为缺少尾随换行符会导致die在代码和函数中附加有关错误位置的信息。你当时正在阅读的任何文件;如果在die参数中包含尾随换行符,则不会发生这种情况。

因此,假设您的文件名包含在变量$filename中,您可以这样做:

$sth = $dbh->prepare('...') || die "$! at $filename line $linenum\n";

哪会导致类似的错误:

DBD::Pg::st_execute failed: ERROR: [...] at /path/to/logfile line 12345