触发器是一种特殊类型的存储过程,它不一样于存储过程。触发器主要是经过事件进行触发而被执行的,而存储过程能够通够存储过程名字而被直接调用。mysql
触发器:trigger,是一种很是接近于js中的事件的知识,提早给某张表的全部记录绑定一段代码,若是该行的操做知足条件(触发),这段提早准备好的代码就会自动执行。sql
一、可在写入数据表以前,强制检验或者转换数据(保证数据安全)数据库
二、触发器发生错误时,异动的结果会被撤销(若是触发器执行错误,那么前面用户已经执行成功的操做也会被撤销:事务安全)安全
三、部分数据库管理系统能够针对数据定义语言(DDL)使用触发器,称为DDL触发器spa
四、可依照特定的状况,替换异动的指令(instead of)。(mysql不支持)code
一、触发器可经过数据库中的相关表实现级联更改。(若是某张表的数据改变,能够利用触发器来实现其余表的无痕操做(用户不知道))对象
二、保证数据安全,进行安全校验blog
一、对触发器过度的依赖,势必影响数据库的结构,同时增长了维护的复杂程度事件
二、形成数据在程序层面不可控。(PHP层)事务
create trigger 触发器名字 触发时机 触发时间 on 表 for each row
begin
end
触发对象:on 表 for each row ,触发器绑定实质是表中的全部行,所以当每一行发生指定的改变的时候,就会触发触发器。
触发时机:每张表中对应的行都会有不一样的状态,当SQL指令发生的时候,都会令行中数据发生改变,每一行总会有两种状态,数据操做前和操做后
before:在表中数据发生改变前的状态
after:在表中数据已经发生改变后的状态
触发事件:mysql中触发器针对的目标是数据发生改变,对应的操做只有写操做(增删改)
insert:插入操做
update:更新操做
delete:删除操做
注意事项:
一张表中,每个触发时机绑定的触发事件对应的触发器类型只能有一个:一张表中只能有一个对应after insert 触发器
所以,一张表中最多的触发器只能有6个:before insert,before update,before delete,after insert,after update,after delete
一、查看所有触发器
show triggers;
二、查看触发器建立语句
show create trigger 触发器名字;
让触发器指定的表中,对应的时机发生对应的操做便可。
基本语法:drop trigger 触发器名字;
触发器针对的是数据表中的每条记录(每行),每行在数据操做先后都有一个对应的状态,触发器在执行以前就将对应的状态获取到了,将没有操做以前的状态(数据)都保存到old关键字中,而操做后的状态都放到new中
在触发器中,能够经过old和new关键字来获取绑定表中对应的记录数据
基本语法:关键字.字段名
old和new并非全部的触发器都有
insert:插入以前为空,没有old
delete:清空数据,没有new
ps:rigger和function中不能出现select * from table形式的查询,由于其会返回一个结果集;而这在mysql的trigger和function中是不可接受的,可是在存储过程当中能够。在trigger和function中可使用select ... into ...形式的查询。
需求:有两张表,一张是商品表,一张是订单表(订单中会保留商品id),每次订单生成,商品表中对应的库存就应该发生变化。
一、建立两张表:商品表,订单表
二、建立触发器:若是订单表发生数据插入,对应的商品就应该减小库存
create trigger 名字 after insert on my_orders for each row
三、触发触发器
-- 建立两张表 create table my_goods( id int primary key auto_increment, name varchar(20) not null, inv int )charset utf8; create table my_orders( id int primary key auto_increment, goods_id int not null, goods_num int not null )charset utf8; insert into my_goods values(null,'手机',1000),(null,'电脑',5000),(null,'平板',100); -- 自动扣除商品库存的触发器 delimiter $$ create trigger a_i_o_t after insert on my_orders for each row begin -- 更新商品库存:new 表明新增的订单 update my_goods set inv = inv - new.goods_num where id = new.goods_id; end $$ delimiter ; -- 触发触发器 insert into my_orders values(null,3,5);
完善:若是库存数量没有商品订单多怎么办?
操做目标:订单表,操做时机:下单前;操做事件:插入事件
-- 判断库存 delimiter $$ create trigger b_i_o_t before insert on my_orders for each row begin -- 取出库存数据进行判断 select inv from my_goods where id = new.goods_id into @inv; -- 判断 if @inv < new.goods_num then -- 中断操做:暴力解决,主动出错 insert into XXX values('XXX'); end if; end $$ delimiter ; insert into my_orders values(null,3,100);
触发器一旦出错,就会撤销以前操做。