Reputation: 47
This is my perl sample code and what i needed is add a timestamp into columns when data changed(updated).
use strict;
use DBI;
use POSIX qw(strftime);
my $datestring = strftime "%Y-%m-%d %H:%M:%S",localtime;
my $dbh = DBI->("dbi:mysql:dbname=perldb","root","111111",{RaiseError=>1})
or die DBI::errstr();
my $mac1='mac1';
my $ip1='ip1';
my $mac2='mac2';
my $ip2='ip2';
$dbh->do("DROP TABLE IF EXISTS Test1");
$dbh->do("CREATE TABLE Test1(Id INT PRIMARY KEY AUTO_INCREMENT,IP TEXT,MAC TEXT,TIME DATETIME,PrevTime DATETIME) ENGINE=InnoDB");
$dbh->do("CREATE Trigger trigger1 AFTER INSERT ON Test1
FOR EACH ROW
BEGIN
IF OLD.MAC!=NEW.MAC
THEN SET NEW.TIME='$datestring';
END IF;
END;")
$dbh->do("INSERT INTO Test1(IP,MAC) VALUES('$ip1','$mac1') ON DUPLICATE KEY UPDATE IP=VALUE(IP)");
$dbh->do("INSERT INTO Test1(IP,MAC) VALUES('$ip2','$mac2') ON DUPLICATE KEY UPDATE IP=VALUE(IP)");
$dbh->disconnect();
The goal I want to reach is run this code once then modify $mac1 to 'mac3'.
So that it will trigger SET timestamp because the data was changed.
Also SET old one timestamp to PrevTIME, but OLD for INSERT.
Result I need maybe like this:
+----+------+------+---------------------+----------+
| Id | IP | MAC | TIME | PrevTime |
+----+------+------+---------------------+----------+
| 1 | ip1 | mac1 | 2015-03-03 12:34:56 | NULL |
| 2 | ip2 | mac2 | 2015-03-03 12:34:56 | NULL |
+----+------+------+---------------------+----------+
Then
+----+------+------+---------------------+---------------------+
| Id | IP | MAC | TIME | PrevTime |
+----+------+------+---------------------+---------------------+
| 1 | ip1 | mac3 | 2015-03-03 12:40:00 | 2015-03-03 12:34:56 |
| 2 | ip2 | mac2 | 2015-03-03 12:34:56 | NULL |
+----+------+------+---------------------+---------------------+
Anyidea? Please help me figure out,THANK YOU.
-------------------------------SOLUTION---------------------------------------
use strict;
use DBI;
use POSIX qw(strftime);
my $datestring = strftime "%Y-%m-%d %H:%M:%S",localtime;
my $dbh = DBI->("dbi:mysql:dbname=perldb","root","111111",{RaiseError=>1})
or die DBI::errstr();
my $mac1='mac1';
my $ip1='ip1';
my $mac2='mac2';
my $ip2='ip2';
$dbh->do("CREATE TABLE IF NOT EXISTS Test1(Id INT PRIMARY KEY AUTO_INCREMENT,IP TEXT,MAC TEXT,TIME DATETIME,PrevTime DATETIME,UNIQUE(IP)) ENGINE=InnoDB");
$dbh->do("CREATE Trigger trigger1 BEFORE INSERT ON Test1
FOR EACH ROW
BEGIN
SET NEW.TIME='$datestring';
END;")
$dbh->do("CREATE Trigger trigger2 BEFORE UPDATE ON Test1
FOR EACH ROW
BEGIN
IF OLD.MAC <> NEW.MAC
THEN
SET NEW.PrevTIME=OLD.TIME;
SET NEW.TIME='$datestring';
END IF;
END;")
$dbh->do("INSERT INTO Test1(IP,MAC) VALUES('$ip1','$mac1') ON DUPLICATE KEY UPDATE IP=VALUE(MAC)");
$dbh->do("INSERT INTO Test1(IP,MAC) VALUES('$ip2','$mac2') ON DUPLICATE KEY UPDATE IP=VALUE(MAC)");
$dbh->disconnect();
Upvotes: 0
Views: 2166
Reputation: 44844
You actually need 2 triggers one before insert
and one before update
. The before insert will set the TIME to now()
, while the before update will check the old and new values of mac and set the PrevTime
to old TIME and TIME to now()
Here are the triggers, you can have them in your code
delimiter //
create trigger trigger1 before insert on Test1
for each row
begin
set new.TIME = now();
end ; //
delimiter //
create trigger trigger2 before update on Test1
for each row
begin
if old.MAC <> new.MAC then
set new.PrevTime = old.TIME ;
set new.TIME = now();
end if;
end ;//
Upvotes: 3
Reputation: 24002
Triggers are event specific.
You are using an INSERT
and hence AFTER
or BEFORE
Trigger works defined for INSERT
events.
You actually need a BEFORE UPDATE
trigger.
Add a similar trigger for BEFORE TRIGGER
Example:
CREATE TRIGGER bu_on_Test BEFORE UPDATE ON Test1
FOR EACH ROW
BEGIN
IF OLD.MAC <> NEW.MAC THEN
SET NEW.TIME='$datestring';
END IF;
END;
But note that Triggers won't take dynamic input parameters like '$datestring'
.
If such a value is set in your scripting language, that is for lifetime of trigger definition and is not going to change during its execution.
Upvotes: 0