1.什么是触发器?
监视一个表动作,在发生动作时,触发事件。
简单理解就是但一个表发生Insert/update/delete 等操作的之前或者之后,执行预先编写好的Sql语句。
2.触发器四个要素是什么?
监视谁(table) 监视条件(insert/update/delete)
触发时间(before /after) 触发事件(inser/update/delete)
3.实列
创建一个store的数据库,并创建ord(订单表)和goods(商品表)两张表并填写数据。
create database store; use store; create table goods(gid int,name varchar(20),num smallint); create table ord(oid int, gid int,much smallint); insert into goods values (1,'cat',34),(2,'pig',65),(3,'dog',23); select * from ord; select * from goods;
如果下订单,购买了12只猫,
如果没有触发器,其操作分两步:
insert into ord value(123,1,12); update goods set num = num-12 where gid = 1;
如果定义触发器如下:
DELIMITER $$; create trigger t2 after insert on ord for each row begin update goods set num = num-new.much where gid = new.gid; end$;
当ord表insert一条语句时,goods表相应的商品会自动减少相应的数量。
4.before和after的区别?
# 如果剩余 1只猫,订单却有10只,发生什么情况,能否预防。
#能否在购买量much>库存量时,把much自动改为num,
#提示:before
drop trigger t2;
DELIMITER $$; create trigger t3 before insert on ord for each row begin declare rnum int; select num into rnum from goods where gid = new.gid; if new.much > rnum then set new.much = rnum; end if; update goods set num = num-new.much where gid = new.gid; end;
1)对于监视同一个表的同一个动作只能有同一个触发器。
2)delimiter $$:对于Mysql 的每条sql语句,都是以“;”结尾,每次执行都是以“;”作为指令结束.
在存储过程或者触发器中“;”往往不代表指令结束,DELIMITER原本就是“;”的意思,因此用这个命令转换一下“;”为“$$”,只有收到“$$”才认为指令结束可以执行。
3)new代表需要插入的那条新数据,old代表需要删除的那条旧数据.
4) afer是在监视动作完成后,执行触发动作,
before 是监视动作还未完成,执行了触发动作在执行触发动作。
5.for each row 的作用?
#每一行受影响,触发器都执行,叫做行级触发器
1)orcle数据库支持表级锁和行级锁
#如果订单包含了5件商品,insert 5次,可以用行级触发器5次修改库存。
不写fore ach row,无论影响多少行都只执行一次。
2)mysql只支持行级锁,目前mysql不支持,所以for each row 必须写。