对数据库触发器new和old的理解

在数据库的触发器中常常会用到更新前的值和更新后的值,全部要理解new和old的做用很重要。当时我有个状况是这样的:我要插入一行数据,在行要去其余表中得到一个单价,而后和这行的数据进行相乘的到总金额,将该行的金额替换成相乘的结果。sql

一开始我使用的after,而后对自身的值进行更改。数据库

  insert update delete
old null 实际值 实际值
new 实际值 实际值 null

在Oracle中用:old:new表示执行前的行,和执行后的行。在MySQL中用oldnew表示执行前和执行后的数据。this

问题的起源

以前对数据库的触发器是这样写的,spa

1 CREATE TRIGGER triggerName after insert ON consumeinfo
2     FOR EACH ROW
3     BEGIN
4       UPDATE consumeinfo SET new.金额=0;
5     END;
 

触发器建立没问题,可是插入数据出现如下错误。code

[Err] 1442 - Can't update table 'consumeinfo' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

可是经过上网搜索的结果说对本表进行修改不用使用update consumeinfo,直接使用SET new.金额=0。这个作法对的,由于这样使用new先对当前的金额改变了,而后存到数据库中的,不用使用update consumeinfo。blog

通过一番努力,如下是成功后的代码,贴出来看看ci

CREATE TRIGGER addnewReco BEFORE INSERT ON consumeinfo FOR EACH ROW
BEGIN
SET new.金额 = (
    SELECT `单价`
    FROM pricenow
    WHERE `类型` = new.类型
    ) * new.数量;
END;

后来在吃饭打汤喝的时候忽然想到new和old在after和before上使用状况不一样。其实仍是由于new不能在after进行赋值,只能进行读取,复制要在before时赋值。it

new和old的使用状况

下面具体说说old和new的使用状况。在对new赋值的时候只能在触发器before中只用,在after中是不能使用的,好比(如下是正确的)。io

CREATE TRIGGER updateprice
BEFORE insert
ON consumeinfo
FOR EACH ROW
BEGIN
   set new.金额=0;
END;

这个说明对当前插入数据进行更新的时候使用before先更新完,而后才插入到数据库中的,在after的触发器中,new的赋值已经结束了,只能读取内容。 若是使用after不能使用new赋值,只能取值,不然会出错误,好比table

1 CREATE TRIGGER updateprice
2 AFTER insert
3 ON consumeinfo
4 FOR EACH ROW
5 BEGIN
6     set new.金额=0;
7 END;

出现这样的错误:

[Err] 1362 - Updating of NEW row is not allowed in after trigger
 
 

总结:new在before触发器中赋值,取值;在after触发器中取值。old在用于取值?由于赋值没意义?

相关文章
相关标签/搜索