对数据库触发器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 ...
随机推荐
- 2.5---链表来进行加法,链式A+B(CC150)
这里是用了自己的方法,和书本不一样. import java.util.HashSet; import java.util.Set; class ListNode{ int val; ListNode ...
- phpcms的评论改为留言板研究
研究背景: phpcms里面默认是没有留言板的,之前我的博客里发过一个二次开发简介,里面有一个简单的留言板,包含前台提供表单,后台留言审核等功能,但是不提供用户登录等操作. 研究思路: phpcms里 ...
- php多线程抓取信息测试例子
php多线程抓取信息测试例子 PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程.多线程在处理重复性的循环任务,能够大大缩短程序执行时间. PHP扩展下载:htt ...
- TCP三次握手原理详解
TCP/IP协议不是TCP和IP这两个协议的合称,而是指因特网整个TCP/IP协议族. 从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层.网络层.传输层.应用层. TCP协议:即传输控制 ...
- Fraction to Recurring Decimal
Given two integers representing the numerator and denominator of a fraction, return the fraction in ...
- 将数据导入带模板EXCEL
在EXCEL模板里设置好样式和格式 点击事件 private void btnReport_Click(object sender, EventArgs e) { ...
- 【转】.so兼容32位和64位
本文转自:http://blog.csdn.net/fwt336/article/details/51700300 安卓的兼容性是一个很令人头疼的问题,这几天又遇到了,还好还是解决了. 我遇到的问题是 ...
- Java 多线程Socket编程通讯--实现聊天室代码
1.创建服务器类 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import ja ...
- TokuDB 引擎安装测试
背景: TokuDB引擎是有Tokutek开发的一个数据库存储引擎,在设计之初便引入了独特的索引算法,在其官网测试的文章中看到TokuDB性能比InnoDB高出很多. MySQL是一个插件式的数据库, ...
- CentOS 6.6 (Desktop)部署Apache、MySQL以及Eclipse Luna等记录
内容较多,持续更新(2015-03-12 16:37:05) *如果没有特别说明,以下操作都是在root账号下完成,图形界面为GNOME. 一.防火墙 先从防火墙入手,为了后续的环境搭建,需要打开80 ...