trigger 触发器(mysql)

/*
触发器 tigger
引出触发器:
      在进行数据库应用软件的开发的时候,我们有时候会碰到表中的某些数据改变,同事希望引起其他相关数据改变的需求,这时候就需要使用触发器。
      运用触发器可以简化程序,增加程序的灵活性
触发器是什么?
       触发器是一种特殊的事务,可以监视某种数据操作(增、删、改),并触发相关操作(增、删、改)
触发器应用场景:
        订单产生,库存减少
        客户消费,积分变化等

触发器的创建语法
        四要素:
        监视地点(table)  监视事件(insert、update、delete)    触发时间(after、before)   触发事件(insert、update、delete)

 查看已有triggers:
              show triggers
 删除触发器
              drop tigger tiggername
 触发器使用监视表改变数据: new(新行)   old(旧行)  

*/

/*
需求:
商品表:goods
订单表:ord

当下一个订单时,对应的商品要相应减少(买几个商品就少几个库存)

分析:
监视谁:ord
监视动作:insert
出发时间:after
触发事件:update
*/
drop table goods;
drop table ord;
create table goods
(
 gid int,
 name varchar(20),
 num smallint
);
create table ord
(
 oid int,
 gid int,
 munch smallint
);

insert into goods
values (1,‘cat‘,34),(2,‘dog‘,65),(3,‘pig‘,21);

--现在我希望我下订单的时候猫的数量减少2只。
--第一个触发器
create trigger t1
after
insert
on ord
for each row
begin
update goods set num=num-2 where gid=1;
end;

--买2只猫,我们发现goods表猫的数量自己减少了2个
insert into ord values (123,1,2);
select * from goods;
--触发器完成了我们的要求吗?我再生成一个买3只猪的订单,发现变得还是猫,还是减少两个
insert into ord values (124,3,3);
select * from goods;
--前面的触发器无法实现我们的要求是因为我们在 update goods set num=num-2 where gid=1; 改变是固定的
-- 可以使用参数吗?在触发器中,如果可以,应该使用什么呢?
-- 被监视的语句中的数据元素可以被我们得到吗?

-- 新增的列使用new得到,删除的列使用old得到
create trigger t12
after
insert
on ord
for each row
begin
update goods set num=num-new.munch where gid=new.gid;
end;
--添加第二个触发器失败,因为不能针对同一个列,在同一个操作,同一个时刻有两个触发器,所以我们将前面的触发器删除
show triggers;
drop trigger t1;

--新增了得到了触发器。
--为了便于显示,我先将订单表清空
truncate ord;
select * from ord;
select * from goods;
--现在我想要订单买2只狗
insert into ord values (123,2,2);
--买一只猫
insert into ord values (124,1,1);
--发现现在的触发器满足我们的需求了

--举一反山,使用old关键字触发器控制当订单表删除订单的时候,将订单中的所属动物返还

create trigger t3
after
delete
on ord
for each row
begin
update goods set num=num+old.munch where gid=old.gid;
end;

delete from ord where oid=124;
-- 发现达到我们效果了

-- 订单改变的时候goods也随之改变
create trigger t4
after
update
on ord
for each row
begin
update goods set num=num+old.munch-new.munch where gid=new.gid;
end;

select * from ord;
select * from goods;
update ord set munch=17 where gid=2;

--before目前似乎并没有看出与after的区别
--一个问题:如果剩余3头猪,但是客户买了十头猪会发生什么情况?能否预防
-- 发现现在dog有21头,如果我订单买32头猪,试试
insert into ord values (124,3,32);
select * from goods;-- 我发现猪变成负数了,这时候,我觉得有必要在订单增加后做一些判断以及对应的操作
-- 我先将错误订单删除,退回到前面的状态
delete from ord where oid=124;
--现在,我希望修改前面的t12触发器,使他达到我的要求
--先删除再添加
drop trigger t12;
create trigger t2
after
insert
on ord

for each row
begin

declare rnum int;
select num into rnum from goods where gid=new.gid;

if new.munch>rnum
then
    set new.munch=rnum;
end if;

update goods set num=num-new.munch where gid=new.gid;

end;
--我们添加t2触发器报错。提示:updating of new rows is not allowed in after trigger
-- 这是因为我们使用的是after关键字,然后在触发器使用的时候new.munch的值已经确定了并且执行了(关键是执行了),就不能更改了,所以报错。所以这里应该将after改为before

create trigger t2
before
insert
on ord

for each row
begin

declare rnum int;
select num into rnum from goods where gid=new.gid;

if new.munch>rnum
then
    set new.munch=rnum;
end if;

update goods set num=num-new.munch where gid=new.gid;
end;

--我们再测试一下,触发器生效了,改变了订单和goods表,避免了负数
select * from ord;
select * from goods;
insert into ord values (124,3,32);
/*
  我们建立触发器时候的for each row有什么作用呢?为什么要使用它呢?
    从字面上理解,指向每一列。
    其实 for each是指定触发器为行级触发器,行级触发器指的就是每一行对应的改变都会跑一次触发器。就是在一次执行多行语句的操作中会跑多次触发器
在oracle中,触发器分语句级触发器和行级触发器,如果不写for each row表示语句级触发器,只会被触发一次
*/ 

-- 测试一下
select * from ord;
--写一个表记录触发次数
create table ct(coun int);
-- 改变一下那个触发条件为update的触发器
drop trigger t4;
create trigger t4
after
update
on ord
for each row
begin
update goods set num=num+old.munch-new.munch where gid=new.gid;
insert into ct values(5);
end;
--我先执行一次改变,看下效果
update ord set munch=10 where gid=2;
select * from ct;
--插入了一次
update ord set munch=0;
select * from ct; -- 检测出插入了两次

-- 实验一下语句级别触发器 ,真是不巧,mysql暂时不支持语句级别触发器
drop trigger t4;
create trigger t4
after
update
on ord
-- for each row
begin
update goods set num=num+old.munch-new.munch where gid=new.gid;
insert into ct values(3);
end;
时间: 2024-10-13 16:07:37

trigger 触发器(mysql)的相关文章

存储过程和触发器——MySQL

从MySQL5.0版本开始就对存储过程和触发器进行了支持,在MySQL进行学习前,先查看您所使用的版本吧,方法有: 1.$mysql -V  //linux终端下 2.select version();  //mysql下 3. mysql --help | grep Distrib  //linux终端下 在了解您所使用的版本支持情况下再下一步 存储过程  sql语句执行的时候要先编译,然后执行.存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数

触发器--mysql

SHOW TRIGGERS;查看所有触发器 create trigger tg1 after insert on user for each row beginupdate user set name='test' where id=1;end insert into user(name,pass) values('shao','23')$$ CREATE TRIGGER语法 CREATE TRIGGER trigger_name trigger_time trigger_event    ON

数据库 的outfile 备份与还原 视图 事物 触发器 mysql函数和自定义函数

outfile    将数据库的数据导出 select * into outfile 'e://mysqloutfile//1.txt' from 表格名; 备份与还原 不再mysql目录下进行备份,mysqldump -uroot -p 数据库名 +表格名 > 具体的路径名(你要导入到哪里) 如果你想得到多张表的那么就在表格后面加一个表格 还原: 先删除数据库的所有东西 如果删除不了,那么就是还有没有删除干净 新建一个数据库 ,用数据库 找到文件   source +具体的文件;将数据导入 视

Trigger 触发器

本文非原创 一.触发器: 是一种特殊的存储过程,其特殊性在于它并不需要用户来执行. 调用,在表中数据进行修改时,自动执行,来实现复杂的完整性约束, 防止对数据不正确的修改. 1.定义:它是一段能够自动执行的程序,当对象进行 update,insert, delete 时,自动执行,它没有参数,不允许被调用. 2.触发器的优点: (1)级联修改 (2)实现复杂约束 (3)检查数据 (4)控制修改表时合乎业务规则 二.触发器的激活时机: 1.后触发:当引起触发器执行的修改语句执行完成,并通过约束后才

WPF 杂谈——Trigger触发器

笔者在使用的WPF过程中,见过的触发器有三种:Trigger.DataTrigger.EventTrigger.其中最为常用的要属Trigger.至于触发器的作用就是当某个属性的值发生变化,应该去做某事.当然这是笔者自身的理解.比较简单.那么这三者之间有什么不同呢?这便是这章要讨论的目地.WPF的Style笔者喜欢把他看作CSS的样式.那么Trigger触发器你们可以理解为CSS样式中类似于:hover 伪类.这样子笔者做一个列子吧.如下,当鼠标移动在文本上面的,前景色变成为红色. <Grid>

mysql(trigger触发器)

drop trigger IF EXISTS t_trigger; create trigger t_trigger before insert on aaa for each row begin INSERT INTO readandwrite_test.user(time) VALUES (NEW.timeline);end;/* INSERT:将新行插入表时激活触发程序,例如,通过INSERT.LOAD DATA和REPLACE语句.UPDATE:更改某一行时激活触发程序,例如,通过UPD

【PLSQL】详解SQL中的trigger(触发器)

本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创建DML触发器 8.2.3 创建替代(INSTEAD OF)触发器 8.2.3 创建系统事件触发器 8.2.4 系统触发器事件属性 8.2.5 使用触发器谓词 8.2.6 重新编译触发器 8.3 删除和使能触发器 8.4 触发器和数据字典 8.5   数据库触发器的应用举例 触发器是许多关系数据库系统都提供的一项技术.在O

[结]trigger(触发器)摘录

1.触发器: 是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行.即触发器是当某个事件发生时自动地隐式运行.并且,触发器不能接收参数. 2.触发器类型: DML触发器    ORACLE可以在DML语句进行触发,可以在DML操作前或操作后进行触发,并且可以对每个行或语句操作上进行触发.  

Trigger(触发器)和Collider(碰撞器)的区别

参考资料: http://www.ceeger.com/Components/class-BoxCollider.html 要产生碰撞的条件: ①.游戏对象必须要有碰撞体,其中一个要必须带有刚体,碰撞的物体要有相对运动: 在物理模拟中,没有碰撞体的刚体会彼此相互穿过. 触发器事件执行的条件:   ①.两个物体上都要带有碰撞器; ②.至少带有一个刚体,并且两个物体至少有一个把触发器打开; 检测碰撞发生的两种方式: ①.碰撞器    ②.触发器 碰撞器: 包含了很多个组件,比如:Box Collie