我有一个perl脚本,我不想发送重复请求:
请求是“ 2018-03-15 12:30:00”,“指标A”,62岁,我只想发送一次且不发送更多:
在我的mariadb bdd中,我有两行:
SELECT time, measurement, valueOne FROM `metric_values`;
结果:
+---------------------+-----------------+----------+
| time | measurement | valueOne |
+---------------------+-----------------+----------+
| 2018-03-15 12:30:00 | Metric A | 62 |
| 2018-03-15 12:30:00 | Metric A | 62 |
我的perl密码:
use DBI;
open (FILE, 'logfile');
while (<FILE>) {
($word1, $word2, $word3, $word4, $word5, $word6, $word7, $word8, $word9, $word10, $word11, $word12, $word13, $word14) = split(" ");
$word13 =~ s/[^\d.]//g;
if ($word13 > 5) {
if ($word2 eq "Jan") {
$word2 = "01"
}
if ($word2 eq "Feb") {
$word2 = "02"
}
if ($word2 eq "Mar") {
$word2 = "03"
}
if ($word2 eq "Apr") {
$word2 = "04"
}
if ($word2 eq "May") {
$word2 = "05"
}
if ($word2 eq "Jun") {
$word2 = "06"
}
if ($word2 eq "Jul") {
$word2 = "07"
}
if ($word2 eq "Aug") {
$word2 = "08"
}
if ($word2 eq "Sep") {
$word2 = "09"
}
if ($word2 eq "Oct") {
$word2 = "10"
}
if ($word2 eq "Nov") {
$word2 = "11"
}
if ($word2 eq "Dec") {
$word2 = "12"
}
print "'$word5-$word2-$word3 $word4', $word11, $word13 \n";
}
# Connect to the database.
my $dbh = DBI->connect("DBI:mysql:database=db;host=ip",
"titi", 'mp!',
{'RaiseError' => 1}) ;
my $sth = $dbh->prepare(
"INSERT `metric_values` (time, measurement, valueOne) VALUES('$word5-$word2-$word3 $word4', $word11, $word13);")#result is ('2018-03-15 12:30:00', 'Metric A', 62)
or die "prepare statement failed: $dbh->errstr()";
$sth->execute() or die "execution failed: $dbh->errstr()";
print $sth->rows . " rows found.\n";
$sth->finish;
我的日志文件:
Wed Oct 17 04:57:08 2018 : Resource = 'toto' cstep= 'titi' time =23.634s
Wed Oct 17 04:57:50 2018 : Resource = 'toto' cstep= 'titi' time =22.355s
答案 0 :(得分:3)
在评论中,您这样说:
我每5分钟执行一次此脚本,这会在表中创建很多相同的行,我不希望在表中出现同一行
我认为这是正在发生的事情。
每五分钟运行一次程序。每次运行该程序时,都使用与输入完全相同的日志文件。因此,每次都会处理相同的记录,并且每次运行都会插入新的数据副本。
您的现有代码没有任何问题。它正在按照您要求的去做。只是不够聪明。您需要使其更聪明。您有几种选择。
REPLACE
代替INSERT
,并确保表上具有正确的主键,以确保不会插入重复的记录。在不了解有关特定应用程序的日志的情况下,很难知道这些选项中的哪一个是最适合您的方法。我怀疑您会发现REPLACE
选项最容易实现。
更新:我希望您会发现一些对代码有用的一般注释。
您打开文件的代码当然可以工作,但是与当前的最佳做法有些距离。我建议a)使用词法文件句柄,b)使用open()
的三参数版本,c)检查调用的返回值。
open my $fh, '<', 'logfile'
or die "Could not open 'logfile': $!\n";
使用名为$word1
,$word2
等的变量是一个糟糕的主意。更好的主意是使用数组:
my @words = split ' ',
如果您确实想要单个变量,请给它们更好的名称:
my ($day, $mon, $date, $time, $year, ... ) = split(' ');
我个人将每条记录变成一个哈希。
my @cols = qw[day mon date time year ... ];
# and then, in your loop
my %record;
@record{@cols} = split ' ';
将月份转换为数字很麻烦。考虑设置转化哈希。
my %months = (
Jan => 1,
Feb => 2,
...
);
然后您的代码变为(假设$mon
而不是$word2
):
$mon = sprintf '%02d', $months{$mon}
or die "$mon is not a valid month\n";
但是,实际上,您应该使用Time::Piece之类的东西来处理日期和时间。
my $timestamp = "$day $mon $date $time $year";
my $tp = Time::Piece->strptime($timestamp, '%a %b %d %H:%M:%S $Y');
say $tp->ymd, ' ', $tp->hms;