Mysql触发器字段双向更新方式

 更新时间:2023年08月30日 09:34:50   作者:大鹏的世界  
这篇文章主要介绍了Mysql触发器字段双向更新方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Mysql触发器字段双向更新

业务场景

不同的业务系统共用余额,hjmallind_user和ims_cjdc_user两个表不同的余额字段,但是共用余额值。

触发器定义

DROP TRIGGER IF EXISTS `test-up_ds_wallet`;
CREATE  TRIGGER `test-up_ds_wallet` AFTER UPDATE ON `ims_cjdc_user` 
    FOR EACH ROW 
    BEGIN
        DECLARE ds_money decimal(10,2);
        IF new.wallet <> old.wallet THEN
            select money into ds_money from hjmallind_user where ptuserid=new.id;
            #解决触发器死循环
            IF ds_money <> new.wallet THEN
                UPDATE hjmallind_user set money=new.wallet where ptuserid=new.id;
            END IF ;
      END IF ;
    END;
DROP TRIGGER IF EXISTS `test-up_wm_wallet`;
CREATE  TRIGGER `test-up_wm_wallet` AFTER UPDATE ON `hjmallind_user` 
    FOR EACH ROW 
    BEGIN
        DECLARE wm_wallet decimal(10,2);
        IF new.money <> old.money THEN
            select wallet into wm_wallet from ims_cjdc_user where id=new.ptuserid;
            #解决触发器死循环
            IF wm_wallet <> new.money THEN
                UPDATE ims_cjdc_user set wallet=new.money where id=new.ptuserid;
            END IF ;
        END IF ;
    END;

校验代码

select id,wallet from ims_cjdc_user where id=164438;
select id,ptuserid,money from hjmallind_user where ptuserid=164438;
-- update hjmallind_user set money=money+50 where ptuserid=8426;
update ims_cjdc_user set wallet=wallet+20.50 where id=164438;
select id,wallet from ims_cjdc_user where id=164438;
select id,ptuserid,money from hjmallind_user where ptuserid=164438;

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

在数据库的触发器中经常会用到更新前的值和更新后的值,所有要理解new和old的作用很重要。

当时我有个情况是这样的:

我要插入一行数据,在行要去其他表中获得一个单价,然后和这行的数据进行相乘的到总金额,将该行的金额替换成相乘的结果。

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

insertupdatedelete
oldnull实际值实际值
new实际值实际值null

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

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

问题的起源

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

CREATE TRIGGER triggerName after insert ON consumeinfo
    FOR EACH ROW
    BEGIN
      UPDATE consumeinfo SET new.金额=0;
    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赋值,只能取值,否则会出错误,比如

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

出现这样的错误:

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

总结

new在before触发器中赋值,取值;在after触发器中取值。

old在用于取值?因为赋值没意义?

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL分类排名和分组TOP N实例详解

    MySQL分类排名和分组TOP N实例详解

    大家好,本篇文章主要讲的是MySQL分类排名和分组TOP N实例详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • mysql的3种分表方案

    mysql的3种分表方案

    这篇文章主要介绍了mysql的3种分表方案,先从为什么要分表说起,然后分析了3种方法的优劣势,最后做了一个总结,需要的朋友可以参考下
    2014-05-05
  • MySQL5.6.22安装配置方法图文教程

    MySQL5.6.22安装配置方法图文教程

    这篇文章主要为大家详细介绍了MySQL5.6.22安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 带例子详解Sql中Union和Union ALL的区别

    带例子详解Sql中Union和Union ALL的区别

    这篇文章主要介绍了带例子详解Sql中Union和Union ALL的区别,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • mysql从一张表查询批量数据并插入到另一表中的完整实例

    mysql从一张表查询批量数据并插入到另一表中的完整实例

    这篇文章主要给大家介绍了关于mysql从一张表查询批量数据并插入到另一表中的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • mysql定时任务(event事件)实现详解

    mysql定时任务(event事件)实现详解

    这篇文章主要介绍了mysql定时任务(event事件)实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • MySQL学习笔记5:修改表(alter table)

    MySQL学习笔记5:修改表(alter table)

    我们在创建表的过程中难免会考虑不周,因此后期会修改表修改表需要用到alter table修改表语句,接下来详细介绍,需要的朋友可以参考下
    2013-01-01
  • MySQL ALTER语法的运用方法

    MySQL ALTER语法的运用方法

    我们今天主要向大家介绍的是MySQL ALTER语法的实际运用,如果你对这一技术,心存好奇的话,以下的文章将会揭开它的神秘面纱。
    2010-11-11
  • MySQL中int (10) 和 int (11) 的区别

    MySQL中int (10) 和 int (11) 的区别

    这篇文章主要介绍了MySQL中int (10) 和 int (11) 的区别,根据mysql 中整数数据类型、不同类型的取值范围、不同数据类型的默认显示宽度展开对int的介绍,需要的朋友可以参考一下
    2022-01-01
  • Mysql日志文件和日志类型介绍

    Mysql日志文件和日志类型介绍

    这篇文章主要介绍了Mysql日志文件和日志类型介绍,本文讲解了日志文件类型、错误日志、通用查询日志、慢速查询日志、二进制日志等内容,需要的朋友可以参考下
    2014-12-12

最新评论