zoukankan      html  css  js  c++  java
  • 对数据库触发器new和old的理解

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

    一开始我使用的after,然后对自身的值进行更改。

     insertupdatedelete
    old null 实际值 实际值
    new 实际值 实际值 null

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

    问题的起源

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

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

    触发器创建没问题,但是插入数据出现以下错误。

    [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。

    经过一番努力,以下是成功后的代码,贴出来看看

    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时赋值。

    new和old的使用情况

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

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

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

    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在用于取值?因为赋值没意义?

  • 相关阅读:
    Oracle 操作数据库(增删改语句)
    web----框架基础
    js----DOM对象
    易错之for循环
    python调用修改变量新方法
    js----基础
    web----Twisted
    web----Socket
    python----面向对象(2)
    python----面向对象
  • 原文地址:https://www.cnblogs.com/joyco773/p/5787088.html
Copyright © 2011-2022 走看看