在数据库的触发器中经常会用到更新前的值和更新后的值,所以要理解new和old的作用很重要。当时我有个情况是这样的:我要插入一行数据,插入的时候要触发将gmt_create字段设置为当前时间,还有更新的时候要触发更新gmt_modified字段为当前时间。
一开始我使用的after,然后对自身的值进行更改。
-- 插入触发器
CREATE TRIGGER insert_help_record_gmt_create AFTER INSERT ON help_record FOR EACH ROW
BEGIN
UPDATE help_record
SET new.gmt_create = now();
END;
-- 更新触发器
CREATE TRIGGER update_help_record_gmt_modified AFTER UPDATE ON help_record FOR EACH ROW
BEGIN
UPDATE help_record
SET new.gmt_modified = now();
END;
该语句创建触发器没问题,但是在插入数据的时候就会报错:
[Err] 1442 - Can't update table 'help_record' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
通过上网搜索的结果说对本表进行修改不用使用update tablename,直接使用SET new.column=now()。这个做法对的,因为这样使用new先对当前的字段值改变了,然后存到数据库中的,不用使用update tablename。
经过一番努力,以下是成功后的代码:
CREATE TRIGGER insert_help_record_gmt_create BEFORE INSERT ON help_record FOR EACH ROW
BEGIN
SET new.gmt_create = now();
END;
CREATE TRIGGER update_help_record_gmt_modified BEFORE UPDATE ON help_record FOR EACH ROW
BEGIN
SET new.gmt_modified = now();
END;
需要注意的是:new和old在after和before上使用情况不同。因为new不能在after进行赋值,只能进行读取。赋值要在before时就赋值。当前插入数据进行更新的时候是使用before先更新gmt_create字段,然后才插入到数据库中的,在after的触发器中,new的赋值已经结束了,只能读取内容。 如果使用after,则不能使用new赋值,只能取值,否则会出错误,比如:
CREATE TRIGGER insert_help_record_gmt_create AFTER INSERT ON help_record FOR EACH ROW
BEGIN
SET new.gmt_create = now();
END;
[Err] 1362 - Updating of NEW row is not allowed in after trigger
网友评论