2015-03-03 26 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'
如果在您的腳本語言中設置了這樣的值,那就是觸發器定義的生命週期,並且在其執行過程中不會改變。