2015-03-03 24 views
0

这是我的perl示例代码,我需要的是当数据更改(更新)时将时间戳添加到列中。

MySQL插入后触发并添加数据更改时的时间戳

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,但将旧的时间戳设置为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(); 

回答

1

你实际上需要2触发器一个before insert和一个before update。在之前的插入会的时间为now(),而之前更新将检查MAC的新旧值,并设置PrevTime旧次地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 ;// 
+0

你好,再次感谢你回答我的问题。 – 2015-03-04 02:37:25

+0

但是'ON DUPLICATE KEY UPDATE'似乎不算作更新,因此更新的触发器将不起作用。 – 2015-03-04 02:39:18

+0

和插入的触发器再次工作。表格的结果将被两个TIME修改。 PrevTIME仍然是NULL。 – 2015-03-04 02:41:28

0

触发器是事件具体。

您正在使用INSERT,因此AFTERBEFOREINSERT事件定义的触发器工作。

您实际上需要一个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'
如果在您的脚本语言中设置了这样的值,那就是触发器定义的生命周期,并且在其执行过程中不会改变。