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

时间:2015-03-03 10:48:53

标签: mysql perl

这是我的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();

2 个答案:

答案 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事件定义的BEFOREINSERT触发器工作。

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