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

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

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

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

时间: 2024-08-27 00:49:44

对数据库触发器new和old的理解的相关文章

数据库触发器详讲

一:触发器的概念: 数据库触发器是一个与表相关联的,存储的plsql语句. 作用:每当一个特定的数据操作语句,(insert,update,delete)在指定的表发出时,Oracle自动地执行触发器中定义的语句序列 第一个触发器:每当成功插入新员工后   自动打印“插入新员工成功” create trigger 触发器名字(saynewemp) after (执行操作之后) insert on 操作的表(emp) declare begin dbms_output.put_line('成功插入

更新数据库触发器

//复制优惠券表解钩 Use HSHDBNew SELECT * INTO TempExistCoupon FROM DiscountActivityPager WHERE 1=2 --update触发器 Create TRIGGER tri_update   ON  DiscountActivityPager           AFTER update  as begin  if update(UDSateID) and (select top 1 UDSateID  from Discou

【赵强老师】利用数据库触发器实现数据的同步

一.什么是触发器 数据库触发器是一个与表相关联的,存储的PL/SQL 语句.每当一个特定的数据操作语句(insert update delete)在指定的表上发出时,Oracle自动执行触发器中定义的语句序列. 触发器的应用场景如下: 复杂的安全性检查 数据的确认 数据库审计 数据的备份和审计 二.创建Oracle触发器的语法 CREATE [OR REPLACE] TRIGGER trigger_name {BEFORE | AFTER } {INSERT | DELETE | UPDATE

Oracle数据库——触发器的创建与应用

一.涉及内容 1.理解触发器的概念.作用和类型. 2.练习触发器的创建和使用. 二.具体操作 (实验) 1.利用触发器对在scott.emp表上执行的DML操作进行安全性检查,只有scott用户登录数据库后才能向该表中执行DML操作.(第1题中,user是系统函数,返回当前用户.字符串中使用两个单引号表示一个单引号.) 要求:分别以system用户和scott用户对emp 表执行DML操作,试验触发器的运行效果. (1)在scott用户下创建触发器 语句: create or replace t

数据库触发器

触发器的作用 [1] 触发器有如下作用: 可在写入数据表前,强制检验或转换数据. 触发器发生错误时,异动的结果会被撤销. 部份数据库管理系统可以针对数据定义语言(DDL)使用触发器,称为DDL触发器. 可依照特定的情况,替换异动的指令 (INSTEAD OF). 2分类 [2] SQL Server 包括三种常规类型的触发器:DML 触发器.DDL 触发器和登录触发器. DML触发器 当数据库中表中的数据发生变化时,包括insert,update,delete任意操作,如果我们对该表写了对应的D

数据库-- 触发器

触发器是特殊的存储过程,它的执行不由程序调用,也不是手动启动,而是由事件来触发,比如当对一个表进行操作(INSERT.UPDATE.DELETE等,不包括SEARCH)时就会被激活,从而执行.另外一个与存储过程不同的地方在于,存储过程更多的是为了返回数据,而触发器更多的作用是维护数据完整性.所以触发器经常用于加强数据的完整性约束和业务规则等. 触发器有三种常规的类型:DML触发器.DDL触发器和登陆触发器. DDL触发器:当服务器或数据库中发生数据定义语言(DDL)事件时会调用DDL触发器. 登

数据库三大范式,我的理解

数据库三大范式,我之前是知道的,但是内容比较文绉绉,初学的时候不容易把握其根本. 首先是第一范式: 有主键,且数据库表的每一列都是不可分割的原子数据项.也可以理解为:无重复的列. 其实这句话的本质是控制字段的颗粒度(也许不该用这个词).这个地方的无重复和不可分割是什么意思呢?其实是这样的.首先如果有两个字段,一个叫籍贯,一个叫家乡,是不是就有点蠢?(这个地方不考虑其区别的话). 对重复的第一层理解是有两个字段其实是描述同样的东西,如果表格这么设计了,势必会导致数据的冗余. 第二层理解是,字段也许

msql数据库触发器和连接mysql常用函数

触发器delimiter $$(设置$$为语句结束符)例:delimiter $$create trigger jiaobanfei after update on user1     for each row beginupdate user2 set age=age+(old.num-new.num);update user2 set num=num+1;end$$delimiter; old.age-new.age 删除;drop trigger jiaobanfei; update us

数据库触发器 、包

触发器是特定事件出现的时候,自动执行的代码块.类似于存储过程,但是用户不能直接调用他们. 功能: 1 . 允许 / 限制对表的修改 2 . 自动生成派生列,比如自增字段 3 . 强制数据一致性 4 . 提供审计和日志记录 5 . 防止无效的事务处理 6 . 启用复杂的业务逻辑 开始 : create trigger biufer_employees_department_id   before insert or update   of department_id   on employees