关于Mysql 触发器
首先,测试版本 Mysql 5.6。
然后再看触发器的语法
CREATE [DEFINER = {user
| CURRENT_USER }] TRIGGERtrigger_name
trigger_time
trigger_event
ONtbl_name
FOR EACH ROWtrigger_body
trigger_time
: { BEFORE | AFTER }trigger_event
: { INSERT | UPDATE | DELETE }
这个是联机文档里面查到的资料。其实语法也挺简单。下面上栗子
首先我们先创建2个测试表
CREATE TABLE `test` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `Col1` varchar(50) DEFAULT NULL, `Col2` varchar(50) DEFAULT NULL, `Col3` int(11) DEFAULT NULL, `Col4` float DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; CREATE TABLE `testTri` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `Col1` varchar(50) DEFAULT NULL, `Col2` varchar(50) DEFAULT NULL, `Col3` int(11) DEFAULT NULL, `Col4` float DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
因为只是用于测试,结构上我就随便建了,就创建一个自增列主键就ok了。
然后在testTri表创建一个触发器(创建一个最简单的触发器奏是这样子,简单吧╮(╯_╰)╭)
drop trigger if exists TR_testTri; delimiter // create trigger TR_testTri after insert on testTri for each row begin insert into test(Col1,Col2,Col3,Col4) values (1,2,3,5); end// delimiter ;
然后再 testTri 上面添加一行记录,明显,很顺利地,test表也增加了一行记录。
insert into testTri (Col1,Col2,Col3,Col4) values (1,2,3,4);
结果 test 和 testTri 都写入了一行的记录。
正常的情况就写到这里了。当然罗 Insert 是这样玩,Update/Delete 也是这样玩, Before /After 在mysql 里面也只是执行顺序问题而已。
然后我就测试了集中情况。
1 触发器自行递归,在表 testTri 创建一个触发器,触发内容就是往 testTri 写入一条记录。做一下实验
drop trigger if exists TR_testTri; delimiter // create trigger TR_testTri after insert on testTri for each row begin insert into TR_testTri(Col1,Col2,Col3,Col4) values (1,2,3,5); end// delimiter ;
创建成功,语法上并没有任何问题。然后添加一行记录
insert into testTri (Col1,Col2,Col3,Col4) values (1,2,3,4);
然后华丽丽地报错了。
insert into testTri (Col1,Col2,Col3,Col4) values (1,2,3,4) Error Code: 1442. Can't update table 'testtri' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 0.047 sec
所以验证了不能自己递归自己。
2 2个表相互循环递归,在test 和 testTri 都创建一个触发器,相互写入数据
drop trigger if exists TR_testTri; delimiter // create trigger TR_testTri after insert on testTri for each row begin insert into test(Col1,Col2,Col3,Col4) values (1,2,3,5); end// delimiter ; drop trigger if exists TR_testTri2; delimiter // create trigger TR_testTri2 after insert on test for each row begin insert into testTri(Col1,Col2,Col3,Col4) values (1,2,3,6); end// delimiter ;
创建成功,语法上并没有任何问题。然后添加一行记录
insert into testTri (Col1,Col2,Col3,Col4) values (1,2,3,4);
然后华丽丽地又报错了。
insert into testTri (Col1,Col2,Col3,Col4) values (1,2,3,4) Error Code: 1442. Can't update table 'testtri' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 0.047 sec
证明这种循环引用也是不被允许的。
做了一个这样的简单实验。证明了mysql 在触发器里面不适宜玩太高级的逻辑,不然真的不知道到底错误是怎样出现的。但是相对来说,对于程序的控制也会容易一些,也是有友好的一面~
PS:在下对Mysql 不甚熟练~还请大家指导