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

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

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

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

问题的起源

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

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

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

  1. Mysql数据库触发器调用脚本

    一.数据库触发器 mysql触发器trigger 实例详解 对数据库触发器new和old的理解 示例 二.UDF mySql的UDF是什么 三.安装执行命令UDF mysql触发器调用外部脚本(安装) ...

  2. 数据库触发器new old

    数据库触发器new old: "NEW . column_name"或者"OLD . column_name".这样在技术上处理(NEW | OLD . col ...

  3. sqlserver数据库触发器调用外部exe

    sqlserver数据库触发器调用外部exe,同事可以选择参入参数! sqlserver使用 master..xp_cmdshell 进行外部exe的执行. 使用master..xp_cmdshell ...

  4. 数据库级别DDL操作监控审计、数据库触发器/服务器触发器

    关键词:数据库触发器/服务器触发器  ,数据库级别DDL操作监控审计,禁止修改登录名密码 [1]数据库级别DDL操作监控审计 转自2012示例库,只能数据库级别,不能实例级别 use database ...

  5. Oracle12c中多宿主环境(CDB&PDB)的数据库触发器(Database Trigger)

    Oracle12c中可插拔数据库(PDBs)上的多宿主数据库触发器 随着多宿主选项的引入,数据库事件触发器可以在CDB和PDB范围内创建. 1.   触发器范围 为了在CDB中创建数据库事件触发器,需 ...

  6. SQL 数据库 触发器 、事务

    触发器类型有两种: 1.AFTER(FOR)触发器 在动作执行之后触发(增删改执行完成后,触发器中的代码再执行),不能为视图指定for触发器,只能为表指定该触发器. 2.instead of触发器 可 ...

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

    一.涉及内容 1.理解触发器的概念.作用和类型. 2.练习触发器的创建和使用. 二.具体操作 (实验) 1.利用触发器对在scott.emp表上执行的DML操作进行安全性检查,只有scott用户登录数 ...

  8. mysql数据库 触发器简单实例

    触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/befo ...

  9. oracle 添加登陆数据库触发器--记录IP 地址

    ----触发器--- ---创建中间插入的表 create table session_history tablespace bap_data as (select sid,username,prog ...

随机推荐

  1. 2016年11月14日--SQL创建数据库、表-查、插、删、改

    --创建数据库(create database 数据库名)create database hq20161114go --使用选择数据库(use 数据库名)use hq20161114go --创建学生 ...

  2. 17.4---返回max,不用if

    思路:借助max公式就可以了.max(x,y)=0.5*(x+y+|x-y|) 注意:1,结尾要加(int). 答案: max(x,y)=0.5*(x+y+|x-y|)

  3. Ubuntu编译源码程序依赖查找方法

    ubuntu平时编译源码程序的时候会提示缺少相关的库或是头文件,可以按照以下两种方法进行查找,然后再安装相应的软件包. 1.使用apt-file查找头文件 安装apt-file sudo apt-ge ...

  4. github 多个项目共用同一个key的方法

    后面的项目不用添加ssh keys, 直接在项目下设置合作者(Collaborators), 搜索出去加进去即可免密码传代码.

  5. vncserver改变屏幕分辨率

    vncserver -geometry 1600x1200 转自: http://stackoverflow.com/questions/15816/changing-the-resolution-o ...

  6. 在Py文件中引入django环境

    复制manage.py中的相关代码即可并将文件置于Project文件夹(与manage.py同位置)下 示例: #! /usr/bin/env python # -*- coding:utf- -*- ...

  7. ios 获得设备型号方法

    以前用UIScreen 的大小来判断设备类型,现在有了iphone6 和 iphone6 plus, 这种方法不能用了.因为当程序不提供相应的启动图片时,系统会把程序运行在320*568的size下, ...

  8. ffmpeg-20160515-git-bin

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  9. [转] git fetch与pull

    原文: http://www.tech126.com/git-fetch-pull/ Git中从远程的分支获取最新的版本到本地有这样2个命令:1. git fetch:相当于是从远程获取最新版本到本地 ...

  10. Effective C++ -----条款46:需要类型转换时请为模板定义非成员函数

    当我们编写一个class template,而它所提供之“与此template相关的”函数支持“所有参数之隐式类型转换”时,请将那些函数定义为“class template内部的friend函数”.