对数据库触发器new和old的理解
在数据库的触发器中经常会用到更新前的值和更新后的值,所有要理解new和old的作用很重要。当时我有个情况是这样的:我要插入一行数据,在行要去其他表中获得一个单价,然后和这行的数据进行相乘的到总金额,将该行的金额替换成相乘的结果。
一开始我使用的after,然后对自身的值进行更改。
insert | update | delete | |
---|---|---|---|
old | null | 实际值 | 实际值 |
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在用于取值?因为赋值没意义?
对数据库触发器new和old的理解的更多相关文章
- Mysql数据库触发器调用脚本
一.数据库触发器 mysql触发器trigger 实例详解 对数据库触发器new和old的理解 示例 二.UDF mySql的UDF是什么 三.安装执行命令UDF mysql触发器调用外部脚本(安装) ...
- 数据库触发器new old
数据库触发器new old: "NEW . column_name"或者"OLD . column_name".这样在技术上处理(NEW | OLD . col ...
- sqlserver数据库触发器调用外部exe
sqlserver数据库触发器调用外部exe,同事可以选择参入参数! sqlserver使用 master..xp_cmdshell 进行外部exe的执行. 使用master..xp_cmdshell ...
- 数据库级别DDL操作监控审计、数据库触发器/服务器触发器
关键词:数据库触发器/服务器触发器 ,数据库级别DDL操作监控审计,禁止修改登录名密码 [1]数据库级别DDL操作监控审计 转自2012示例库,只能数据库级别,不能实例级别 use database ...
- Oracle12c中多宿主环境(CDB&PDB)的数据库触发器(Database Trigger)
Oracle12c中可插拔数据库(PDBs)上的多宿主数据库触发器 随着多宿主选项的引入,数据库事件触发器可以在CDB和PDB范围内创建. 1. 触发器范围 为了在CDB中创建数据库事件触发器,需 ...
- SQL 数据库 触发器 、事务
触发器类型有两种: 1.AFTER(FOR)触发器 在动作执行之后触发(增删改执行完成后,触发器中的代码再执行),不能为视图指定for触发器,只能为表指定该触发器. 2.instead of触发器 可 ...
- Oracle数据库——触发器的创建与应用
一.涉及内容 1.理解触发器的概念.作用和类型. 2.练习触发器的创建和使用. 二.具体操作 (实验) 1.利用触发器对在scott.emp表上执行的DML操作进行安全性检查,只有scott用户登录数 ...
- mysql数据库 触发器简单实例
触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/befo ...
- oracle 添加登陆数据库触发器--记录IP 地址
----触发器--- ---创建中间插入的表 create table session_history tablespace bap_data as (select sid,username,prog ...
随机推荐
- 读书笔记-JVM
局部变量表(虚拟机栈中的一部分)在编译期完成分配,运行期不会再改变大小: 每个方法对应一个栈帧(存储局部变量表.操作数栈.动态链接.方法出口等),栈帧被存储到虚拟机栈中,每个线程对应一个虚拟机栈,方法 ...
- NSOperation
自定义operation 相比GCD,可以中断任务,也可使用 addDependency,对要执行的任务进行排序.. // // CustomOperation.h // Test // // Cre ...
- IDEA 编译找不到符号,文件却没有错误。
单独编译提交找不到符号的文件. DIEAA
- TIMIT语音库
TIMIT语音库有着准确的音素标注,因此可以应用于语音分割性能评价,同时该数据库又含有几百个说话人语音,所以也是评价说话人识别常用的权威语音库,但该语音库的商业用途是要花钱买的.下面的资源来自与MIT ...
- Excel导出的几种方式
1.html 前台html与js代码(文件:ExportExcelByHtml.aspx): <html xmlns="http://www.w3.org/1999/xhtml&quo ...
- POJ 3026(BFS+prim)
http://poj.org/problem?id=3026 题意:任意两个字母可以连线,求把所有字母串联起来和最小. 很明显这就是一个最小生成树,不过这个题有毒.他的输入有问题.在输入m和N后面,可 ...
- redis 中文字符显示
2015年5月20日 09:57:01 星期三 方法一: redis-cli -h --raw 方法二: linux 终端: echo -e "\xe7\xa5\x9e\xe6\xa3\x8 ...
- OPCServer Modbus使用和配置
一,安装KEPware.Enhanced.OPC.DDE.KEPServer.(PLC数据传送给KEPServer,开发的程序用OPCServer读KEPServer) 设置ip地址后面是指的plc站 ...
- nginx服务器绑定域名和设置根目录的方法
nginx服务器绑定域名以及设置根目录非常方便,首先进入nginx安装目录,然后执行 vim conf/nginx.conf 打开nginx的配置文件,找到 server { ..... ..... ...
- Python 生产环境MySQL数据库增量备份脚本
MySQL数据库常用的办法是通过MySQLdump导出sql进行备份,但是不适合数据量很大的数据库,速度,锁表是两个严重的问题.前面写了一遍文章介绍xtrabackup的热备工具,见 http://w ...