Perl-don';不发送双sql请求
我有一个perl脚本,不想发送双重请求: 请求是'2018-03-15 12:30:00','Metric A',62,我只想发送一次,而不是更多: 在我的bdd中,我有两行:Perl-don';不发送双sql请求,sql,perl,request,Sql,Perl,Request,我有一个perl脚本,不想发送双重请求: 请求是'2018-03-15 12:30:00','Metric A',62,我只想发送一次,而不是更多: 在我的bdd中,我有两行: SELECT time, measurement, valueOne FROM `metric_values`; 结果: +---------------------+-----------------+----------+ | time | measurement | va
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 scipt:
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;
感谢您在评论中的回复,您可以这样说:
我每5分钟执行一次脚本,在表中创建许多相同的行,我不希望在表中出现相同的行 我认为这就是正在发生的事情 每五分钟运行一次程序。每次运行程序时,都使用与输入完全相同的日志文件。因此,每次都会处理相同的记录,并在每次运行时插入数据的新副本 您现有的代码没有问题。它正在做你要求它做的事情。这还不够聪明。你需要做得更聪明些。你有几个选择
REPLACE
选项最容易实现
更新:我希望您会发现一些关于代码的一般性评论非常有用
当然,您打开文件的代码是有效的,但它与当前的最佳实践有一定距离。我建议a)使用词法文件句柄,b)使用三个参数版本的open()
和c)检查调用的返回值
open my $fh, '<', 'logfile'
or die "Could not open 'logfile': $!\n";
如果您确实需要单个变量,请为它们提供更好的名称:
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
):
但是,实际上,您应该使用类似的方法来处理日期和时间
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;
您的脚本只执行一次插入。如果您多次调用它,它将执行多次插入。如果行已经存在,您实际上是在寻找一种不插入行的方法,对吗?在这种情况下可能会有所帮助。我每5分钟执行一次脚本,在表中创建许多相同的行,我不希望在表中创建相同的行在字段上创建一个唯一的索引,该索引应该是唯一的?@jack:我不确定你真正的问题是什么。这个脚本使用一个固定语句插入一行,这当然会在执行时添加数据,因为这些数据在脚本中是硬编码的。如果您打算在表中只包含这一行,那么为什么要多次执行此脚本?我向您展示了所有代码在(文本)日志文件中添加“已处理”标志可能会涉及每次重新写入整个文件(尽管有很多方法)。避免重新处理日志行的更好方法是使用File::Tail()或类似工具,这样每次新运行都可以从上一次运行结束的地方开始,而不是每次都从文件的开头开始。@DaveSherohman:我并不是说它们都是好的选项:-)
my %months = (
Jan => 1,
Feb => 2,
...
);
$mon = sprintf '%02d', $months{$mon}
or die "$mon is not a valid month\n";
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;