这是我的perl示例代码,我需要的是在数据更改(更新)时将时间戳添加到列中。
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();
我想要达到的目标是运行此代码,然后将$ mac1修改为'mac3'
因此,它会触发SET时间戳,因为数据已被更改
同时将旧的一个时间戳设置为PrevTIME,而将OLD设置为INSERT。
结果我需要这样的:
+----+------+------+---------------------+----------+
| 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 |
+----+------+------+---------------------+----------+
然后
+----+------+------+---------------------+---------------------+
| 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?请帮我弄清楚,谢谢。
------------------------------- 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();
答案 0 :(得分:1)
您实际上需要两个触发器before insert
和一个before update
。之前的插入会将TIME设置为now()
,而之前的更新会检查mac的旧值和新值,并将PrevTime
设置为旧的TIME和TIME为now()
以下是触发器,您可以在代码中使用它们
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 ;//
答案 1 :(得分:0)
触发器是事件特定的。
您正在使用INSERT
,因此为AFTER
事件定义的BEFORE
或INSERT
触发器工作。
您实际上需要BEFORE UPDATE
触发器。
为BEFORE TRIGGER
示例:
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;
但请注意,触发器不会采用动态输入参数,例如'$datestring'
如果在脚本语言中设置了这样的值,那就是触发器定义的生命周期,并且在执行期间不会改变。