最近实验课在做一个商品管理系统,里面有商品goods表和订单明细order_d表,商品表里面有库存数量,订单明细表里面有订购数量。简单来看,1.订购数量>库存数量,插入异常 2.正确订购,订购之后库存数量要减少。简单来说,就是一个量变化了引起另一个量变化,或者进行验证。这里就会用到触发器。写这篇博客一方面是想让自己更熟悉触发器,另一方面是自己讲的或做的不太好的地方希望各位能够不吝赐教,感谢!首先,我会介绍下触发器,然后结合简单实例讲解。
一、触发器介绍
1.概念
触发器是用户定义在关系表上的一类由事件驱动的特殊过程。触发器被保存在数据库服务器中。任何用户对表的增删改操作均由服务器自动激活相应的触发器。它类似于约束,但更加灵活,粒度更细,对数据的控制能力更强大。
2.触发器分类
SQL Server常见触发器类型:DML触发器,DDL触发器,登录触发器。
3.触发器优点
- 集中完整性控制
- 防止非法修改数据
- 进行级联操作
- 返回自定义的错误
- 调用更多存储过程
4.触发器工作原理
触发器在触发时,系统自动在内存中创建inserted表和deleted表。触发器完成后,自动删除deleted表。
inserted表临时会临时保存插入或更新后的记录行,同时可以检查插入或更新的数据是否满足需求,如果不满足则回滚。
deleted表临时保存了删除或更新的记录行,同时可以检查被删除的数据是否满足需求,如果不满足则回滚。
5.定义触发器
表结构如下:
二、简单实例
1.insert触发器
上面已经说了,订购数量要小于库存数量,订购之后库存数量要减少。为此,我们应该在订单明细表上创建触发器,既要判断数量关系又要在满足条件时更新库存数量。当订购数量大于库存数量时,进行回滚操作;当订购数量小于等于库存数量时,更新库存数量。代码如下:
create trigger check_amount on order_d
for insert
as begin
declare @id varchar(50)
declare @order_amount int
declare @amount int
select @id=id,@order_amount=order_amount from inserted
select @amount=amount from goods where id=@id;
/*select @id,@order_amount,@amount;*方便调试/
if (@order_amount>@amount)
begin
Rollback Transaction
end
else
begin
update goods set amount=@amount-@order_amount where id=@id
end
end
实验效果如下:
插入正确数据:
insert into order_d values('001','1',50);
订购数量>库存数量:
2.delete触发器
我们要达到的目的是,删除商品,订单明细里面相应数据也随之删除。这里涉及到级联删除,我们用触发器也可以完成。主要思路是:明确触发条件,明确删表顺序。我们的触发条件就是“删除商品”,删表顺序“先删订单明细表,再删商品表”。代码如下:
create trigger del on goods instead of delete
as begin
declare @id varchar(50)
select @id=id from deleted
delete from order_d where id=@id
delete from goods where id=@id
end
删除对比如下:
删除之前:
删除商品之后: