第12节-MySQL触发器

12.1、触发器介绍

触发器是一种特殊的存储过程,只要满足一定条件,对数据表进行INSERT、UPDATE、DELETE操作时,数据库系统就会自动执行触发器中定义的程序语句,以进行维护数据完整性或其他一些特殊的任务。

触发器是MYSQL的数据库对象之一,与存储过程非常相似,都需要声明﹑执行等。但是触发器的执行不是由程序调用的,也不是手工启动的,而是由事件来触发的。

MySQL提供了两个逻辑表NEW和OLD,NEW和OLD的表结构与触发器所在数据表的结构完全一致,当触发器的执行完成之后,这两个表也会被自动删除。

OLD表用来存放更新前的记录:
对于UPDATE语句,OLD表中存放的是更新前的记录(更新完后即被删除);
对于DELETE语句,该表中存放的是被删除的记录。

NEW表用来存放更新后的记录:
对于INSERT语句,NEW表中存放的是要插入的记录;
对于UPDATE语句,该表中存放的是要更新的记录。

12.2、测试的表结构

CREATE TABLE `student` (
  `sno` varchar(20) NOT NULL,
  `sname` varchar(20) DEFAULT NULL,
  `ssex` enum('','','') DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sdept` varchar(20) DEFAULT NULL,
  `birthday` datetime DEFAULT NULL,
  PRIMARY KEY (`sno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `score` (
  `sno` varchar(20) DEFAULT NULL,
  `courseid` int(11) DEFAULT NULL,
  `grade` tinyint(4) DEFAULT NULL,
  KEY `fk_courseid` (`courseid`),
  KEY `fk_snoid` (`sno`),
  CONSTRAINT `fk_courseid` FOREIGN KEY (`courseid`) REFERENCES `course` (`courseid`),
  CONSTRAINT `fk_snoid` FOREIGN KEY (`sno`) REFERENCES `student` (`sno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

12.3、触发器管理

12.3.1、创建触发器

12.3.1.0、注意事项

请注意:
若有外键约束,这个更新语句执行不成功。
可以通过以下语句让外键约束暂时失效:SET FOREIGN_KEY_CHECKS=0;

12.3.1.1、update触发器

-- 1、update,创建触发器,当sno更新时,则更新score表
-- after:更新之后执行,before:更新之前执行
delimiter $$
create trigger sno_update after update on student for each row
begin
    update score set sno=new.sno where sno=old.sno;
end$$
delimiter ;

-- 更新时,查看触发器,是否生效
update student set sno='99999' where sname='洛燕妮';

12.3.1.2、insert触发器

-- 2、delete,创建触发器,当学生被旧除时,同步删除score表该学生数据
delimiter $$
create trigger sno_delete after delete on student for each row
begin
delete from score where sno=old.sno;
end$$
delimiter ;

-- 测试触发器是否生效
delete from student where sno='99999';

12.3.1.3、delete触发器

-- 3、insert,创建触发器,插入数据时,sno自动+1
delimiter $$
create trigger trig_auto before insert on student for each row
begin
    declare index_sno int;
    select max(sno) into index_sno from student;
    set new.sno=index_sno+1;
end$$
delimiter ;

-- 插入数据,检查是否有更新
insert into student values ('123','ok','',88,'计算机系','2000-01-03 13:12:12');

12.3.2、查看触发器

show triggers;

12.3.3、删除触发器

drop trigger trig_auto;

12.4、实战

12.4.1、实战1【阻止更新某列的数据】

delimiter $$
create trigger sno_update before update on student for each row
begin
    set new.sno=old.sno;
end$$
delimiter ;

12.4.2、实战2【阻止插入数据】

delimiter $$
create trigger check_student before insert on student for each row
begin
declare vcount int;
    select count(ssex) into vcount from student where ssex='';
    if vcount>=8 then
    signal sqlstate '45000' set message_text='不允许插入';
    end if;
end$$
delimiter ;

 

posted @ 2022-11-24 14:40  小粉优化大师  阅读(77)  评论(0编辑  收藏  举报