Perl - Don't Send Double Sql Request
Solution 1:
In a comment, you say this:
i execute this script every 5 minute and that create many same line in the table, i don't want same line in my table
I think this is what is happening.
Every five minutes you run your program. Each time you run the program you use exactly the same log file as input. So the same records get processed every time and new copies of the data are inserted on each run.
There's nothing wrong with your existing code. It's doing exactly what you've asked it to do. It's just not clever enough. You need to make it cleverer. You have a few options.
- Remove from the log file the records that have been processed. That way you only insert each record once.
- Add a flag to each record in your log file which indicates that it has been added to the database. You can then check that flag when processing the file and only insert records that don't have the flag.
- Add an index to your table to ensure that it can only contain one copy of each record. You'll then need to change your code so it ignores any duplicate data errors that you get back from the database.
- Use
REPLACEinstead ofINSERTand ensure you have the correct primary key on your table to ensure that duplicate records aren't inserted.
Without knowing a log more about your particular application, it's hard to know which of these options is the best approach for you. I suspect you'll find the REPLACE option the easiest to implement.
Update: I hope you'll find some general comments on your code to be useful.
Your code to open the file works, of course, but it is some distance from current best practice. I recommend a) using a lexical filehandle, b) using the three-arg version of open() and c) checking the return value from the call.
openmy $fh, '<', 'logfile'ordie"Could not open 'logfile': $!\n";
Using variables called $word1, $word2, etc is a terrible idea. A better idea would be to use an array:
my @words = split' ',
If you really want individual variables, then please give them better names:
my ($day, $mon, $date, $time, $year, ... ) = split(' ');
Personally, I'd turn each record into a hash.
my @cols = qw[day mon date time year ... ];
# and then, in your loopmy %record;
@record{@cols} = split' ';
Converting the month to a number the way you do it is clunky. Consider setting up a conversion hash.
my %months = (
Jan =>1,
Feb =>2,
...
);
Then your code becomes (assuming $mon instead of $word2):
$mon = sprintf'%02d', $months{$mon}
ordie"$mon is not a valid month\n";
But, actually, you should use something like Time::Piece to deal with dates and times.
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;
Post a Comment for "Perl - Don't Send Double Sql Request"