mysql触发器的入门理解和应用

概念:

-- 触发器

-- 特殊的存储过程,主要是通过事件触发而被执行,可以通过存储过程名直接被调用

-- 是一种接近js事件的知识,提前给某个表的所有记录绑定一段代码,

-- 如果操作满足条件触发,这个触发器就会自动执行

作用:

-- 可以在写入数据表之前,强制检验或转换数据(保证数据安全)

-- 触发器发生错误,异动的结果会被撤销(如果触发器执行错误,那么前面已经执行成功的操作夜壶被撤销,事务安全)

优点:

-- 触发器可通过数据中的相关表级联更改(如果某表的数据改变,可以利用触发器来实现其他表的无痕操作)

-- 保证数据安全,进行安全检验

缺点:

-- 对触发器过分的依赖,会影响数据库的结果,增加维护的复杂程度

-- 造成数据在程序层面不可控

语法:

如果只有一条语句 就不需要begin和end

CREATE TRIGGER 名字 触发时机 触发事件 ON 表 for each row

BEGIN

END

触发对象:绑定实质是表中的所有行,因为每一行发生制定的改变,就会触发

触发时机:

当sql指令发生的时候 ,就会让行中数据发生改变,

-- 每一行会有两种状态,数据操作前和操作后

-- BEFORE 在表中数据发生改变前的状态

-- AFTER 表中数据已经发生改变后的状态

触发事件:

发生增删改才会触发 INSERT UPDATE DELETE

一张表中只有一个 AFTER INSERT触发器

一张表最多的触发器只有6个,分别是:

BEFORE INSERT ,AFTER INSERT

BEFORE UPDATE ,AFTER UPDATE

BEFORE DELETE ,AFTER DELETE


示例:产品表,订单表,每次订单生成,商品中的对应的库存就会发生改变

首先创建产品表和订单表

create table my_good(
id int PRIMARY key auto_increment,
name VARCHAR(20)  not null comment'商品名',
inv int COMMENT'库存'
)CHARSET utf8;

create table my_order(
id int PRIMARY key auto_increment,
good_id int not null COMMENT'商品id',
good_num int not NULL
)CHARSET utf8;

插入新的产品

INSERT  into my_good VALUES(null,'手机',1000),(null,'电脑',500),(null,'游戏机',100) 

 创建触发器,如果订单表发生数据插入,对应的商品的库存就会发生改变

delimiter $$
CREATE TRIGGER after_insert_order_t AFTER INSERT on my_order for each ROW
BEGIN 
-- 更新商品库存
UPDATE my_good set inv = inv - 1 where id = 1;
END
$$
delimiter;

 查看所有触发器

show  TRIGGERS 

查看某个触发器

show CREATE TRIGGER after_insert_order_t

删除触发器

drop TRIGGER 触发器名

 插入一条数据之后 ,查看是否能会引起库存的减少

insert into my_order values(null,1,1)

可以看到对应的商品的数量会减少 !

但是可以看到这个触发器是有问题的,因为他的产品id是写固定的,不是根据订单进来的那个商品的id获取在进行改变,

所以我们需要完善


触发器关键字:old 和 new

-- 触发器针对数据表中的每行记录,每行在数据操作前后都有一个对应的状态

-- 触发器在执行之前就将对应的状态获取到

-- 没有操作之前的状态数据都保存old关键字中

-- 而操作之后的状态都放到了new中

-- 在触发器中 可以通过old和new来获取绑定表中对应的记录数据

-- 基本语法:关键字,字段名

-- old和new并不是所有触发器都有

-- INSERT 插入前全为空,没有old

-- DELETE 清空数据,没有new

完善我们的引用示例:

自动改变库存:

重建触发器

delimiter $$
create TRIGGER a_i after INSERT on my_order for each row
BEGIN
	-- 更新库存:使用关键字 new代表新增订单
	-- 库存等于现有库存减去对应订单的产品数量
	-- 库存变动的产品等于订单中的产品
	UPDATE my_good set inv = inv - new.good_num where id = new.good_id;
END
$$
delimiter;

 现在进行测试

insert into my_order values(null,2,5) 

可以发现此时对应的商品的库存会发生改变

但是!

这边有一个问题,如果库存不够了,怎么办?

很明显 我们需要加入判断,并且利用一个触发器的特点 ,一旦出错,之前插入成功的数据都会失效!

判断库存

delimiter $$
-- 表示在插入之前的触发器
CREATE TRIGGER a_b before INSERT on my_order for each ROW
BEGIN
-- 取出库存 并存放到变量中
	select inv from my_good where id = new.good_id into @inv;

-- 判断取出的库存是否满足进单 如果库存小于当前订单中的商品数量
	if @inv < new.good_num THEN
			-- 中断操作
      -- 根据触发器的特点 出错就会将之前的插入成功的失效 
		  -- 所以在判断内写错的语句即可
			INSERT into XXX values("xxx");
	end if;
END
$$
delimiter;

再次进行插入一条订单,让他的数量大于库存,看会不会出现什么效果?

INSERT into my_order values(null,2,1000)

 可以看到 出错了,说明判断成功,并且生成一条订单也失败了!


欢迎进行交流!

猜你喜欢

转载自blog.csdn.net/zhangzeshan/article/details/88394104
今日推荐