一、什么是触发器?
1.概念:
简单来说触发器就是一种特殊的存储过程,在数据库服务器触发事件的时候会自动执行其SQL语句集。
2.构成四要素:
(1)名称:要符合标识符命名规则
(2)定义的目标:必须要定义在表上或者视图上
(3)触发逻辑:触发事件之后如何处理
(4)触发事件类型:
在MySQL中,触发器有时候需要同时表示某个字段更新前后的数据,或者新增的、删除的数据。因此:
- “NEW.列名”表示新增数据行的列或更新后的列
- “OLD.列名”表示更新或删除它之前的已有行的列
触发事件类型 NEW和OLD的使用 INSERT NEW表示将要或者已经新增的数据 UPDATE OLD用来表示将要或者已经被删除的数据,NEW表示将要或者已经修改的数据 DELETE OLD表示将要或者已经被删除的数据
3.种类:
触发器类型 | 描述 |
---|---|
Before触发器 | 在触发事件发生之前执行的触发器 |
After触发器 | 在触发事件发生之后执行的触发器 |
4.与存储过程的区别:
两者最明显的区别就是调用执行方式的不同。
触发器 | 主要是通过事件进行触发而被执行的,具有极强的及时性,代码量也不大,无需人工手动干预去执行。
| |
存储过程 | 可以通过存储过程名字结合CALL语句而被直接调用。 |
二、触发器的作用是什么?
简单一句话来说就是用于强制执行业务规则和数据完整性.
(1)强化约束:能够实现比约束更为复杂的业务规则约束;
(2)跟踪变化:侦测数据库内的操作,从而不允许数据库中未经许可的指定更新和变化,以防止恶意的或者不正确的插入、更新和删除操作;
(3)级联运行:可以侦测数据库内的操作,自动地级联影响整个数据库的相关内容;
(4)差异记录:触发器能够找出某一表在数据修改前后状态发生的差异。并且还可以根据差异执行相应的处理
三、MySQL语句创建、查看(验证)、删除触发器
1.创建触发器
MySQL创建触发器语句的语法如下:
CREATE TRIGGER trigger_name trigger_time trigger_event
ON tb_name FOR EACH ROW trigger_stmt
a. trigger_name:触发器名称。
b.trigger_time:触发时机。也就是选择哪一种触发器,可以是Before也可以是After,表示触发器是在激活其语句之前还是之后触发。
c.trigger_event:触发事件类型。
d.tb_name:建立触发器的基础表。这里要注意的是同一个表不能拥有两个具有相同触发时机和事件的触发器,如果出现两个相同的,那么在语句激活的时候,系统此时不是不知道选择哪一个触发器去执行相应操作,而是会两个一起执行。
e.FOR EACH ROW:表示受触发器影响的每一行激活触发器的动作。比如,对于插入多行数据的sql语句,触发器便会对要插入数据的行执行相应的触发器操作。
f.trigger_stmt:触发器的程序体,也就是触发器激活时要执行的语句集。当需要执行多条语句的时候,需要使用Begin开始标志和End结束标志。
2.查看验证触发器
MySQL查看所有触发器情况语句的语法如下:
SHOW TRIGGERS;
SELECT * FROM information_schema.triggers WHERE TRIGGER_NAME=trigger_name;
其中,trigger_name表示要查看的触发器的名称。
3.删除触发器
MySQL删除触发器语句的语法如下:
DROP TRIGGER 触发器名
四、例题演练
1、创建一个触发器tr_delb:
在图书管理系统中,若删除书籍信息(bookinfo 表)时,需同时删除所有该书籍的借阅信息(BookLended 表)。需实现上述功能,且需通过数据进行验证。
delimiter // create trigger tr_delb After delete on bookinfo FOR EACH ROW begin delete from booklended where bookid=old.bookid; end // delimiter;
(1)创建成功:
(2)删除操作前两张表:
(3)删除操作后两张表:
delete from bookinfo where bookname='数据库系统原理及应用';
2、创建一个触发器tr_upnum。
在图书管理系统中,若插入书籍借阅信息(BookLended 表)时,需同时更新读者表(reader)中该读者的借阅书籍本数(num字段),在原有借阅书籍本数上加1。需实现上述功能,且需通过数据进行验证。
delimiter // create trigger tr_upnum After insert on booklended FOR EACH ROW begin update reader set num=num+1 where readerid=new.readerid; end // delimiter;
(1)创建成功:
(2)添加信息前两张表:
(3)添加信息后两张表:
mysql> insert into booklended(bookid,readerid,lendtime,backtime) values ('21-03-01-012024','1000003112',now(),now());
(ps:这里因为之前创建了一个重名的触发器,也是执行相应操作,数据才会加了两次)