一、什么是触发器
触发器对表进行插入,更新,删除的时候会自动执行的特殊储存过程;
不同于我们学过的储存过程,
触发器主要是通过事件进行触发被自动调用的,储存过程则可以通过储存过程名称进行调用。
二、有什么优点
(1)触发器是自动的,当对表中的数据做了任何修改之后立即被激活,反应迅速,无需写业务代码。
(2) 触发器可通过数据库中的相关表实现级联更改,不过,通过级联引用完整性约束可以更有效地执行这些更改。
触发器可以强制比用CHECK约束定义的约束更为复杂的约束。与 CHECK 约束不同,触发器可以引用其它表中的列。
例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,
以及执行其它操作,如修改数据或显示用户定义错误信息。触发器也可以评估数据修改前后的表状态,
并根据其差异采取对策。一个表中的多个同类触发器(INSERT、UPDATE 或 DELETE)允许采取多个不同的对策以响应同一个修改语句。
三、创建语句
create trigger trigger_name
after\before insert\delete\update
on table_name
for each row
begin
sql ####
end;
四、删除语句
drop trigger trigger_name;
五、demo示例
1.普通情况
##需求1:订单表(ord) 商品表(goods) 插入新订单的时候自动减去商品剩余数量
## 1.监控插入(动态参数使用new对象)
create trigger auto_update_goods
AFTER INSERT
on ord
for each ROW
BEGIN
update goods set num = num-new.much where gid = new.gid;
END;
##需求2:删除新订单的时候自动返还商品剩余数量
## 1.监控删除(动态参数使用old对象)
create trigger auto_update_goods
AFTER delete
on ord
for each ROW
BEGIN
update goods set num = num+old.much where gid = old.gid;
END;
##需求3:修改某个订单的时候自动更新商品剩余数量
## 1.监控修改(动态参数使用old,new 对象)
create trigger auto_update_goods
befor update
on ord
for each ROW
BEGIN
update goods set num = num+old.much-new.much where gid = old.gid;
END;
2.特殊情况,当订单量大于库存量如何避免超卖?
触发时机 必须用before 不能用after(因为要修改insert new的值,然后用new的值 要在即将insert前触发。 要是用after的话,
new的值已经插入进去使用了,再修改没有意义了 )
CREATE TRIGGER t2 BEFORE INSERT ON ord FOR EACH ROW
BEGIN
DECLARE realNum int; #mysql定义需要在begin里面
SELECT
num INTO realNum
FROM
goods
WHERE
gid = new.gid;
IF new.much > realNum THEN
SET new.much = realNum; #超卖时,将全部剩余库存量赋予订单量
END IF;
UPDATE goods
SET num = num - new.much
WHERE
gid = new.gid;
END;
六、注意事项
1.触发器只能在表里设置,且不能重复监控,数据库中的名称不能重复。
2.for each row mysql中是行级触发器,影响多少行就会执行多少次,不能省略该语句,但是在oracle中 该语句可以省略,变为语句级触发器,只执行一次。
网友评论