mysql trigger not in_mysql 触发器 trigger用法 four

实验4 触发器

(1)实验目的

掌握数据库触发器的设计和使用方法

(2)实验内容和要求

定义BEFORE触发器和AFTER触发器。能够理解不同类型触发器的作用和执行原理,验证触发器的有效性。

(3)实验重点和难点

实验重点:触发器的定义。

实验难点:利用触发器实现较为复杂的用户自定义完整性。

此次实验还是延用理论课本中出现的大学数据库作为实验例子。

(1).AFTER触发器

i.  在takes表上定义一个UPDATE触发器,当takes表中元组的属性grade被更新时,意味着学生上的这么课的课程成绩被更新,需要用触发器维护student里元组的tot_cred属性,使其获得的总学分保持实时更新。只有当属性grade从空值或者’F’被更新为代表课程已经完成的具体分数时,触发器才会被激发。

48304ba5e6f9fe08f3fa1abda7d326ab.png

delimiter

create trigger credit_get after update

on takes foreach row

beginif (NEW.grade <> 'F' and NEW.grade is not nulland (OLD.grade = 'F' or OLD.grade is null))

thenupdatestudent

set tot_cred = tot_cred +(selectcredits

fromcourse

where course.course_id =NEW.course_id)

where student.ID =NEW.ID;

end if;

end;

48304ba5e6f9fe08f3fa1abda7d326ab.png

ii.  在section表上定义一个INSERT触发器,当对课程section表执行任何插入操作后触发器被启动,以确保插入元组的time_slot_id属性即上课时间段是合法的,受time_slot表的time_slot_id约束,检查插入时的参照完整性。

48304ba5e6f9fe08f3fa1abda7d326ab.png

delimiter

create trigger timeslot_check1 after insert

on section foreach row

beginif(NEW.time_slot_id not in(selecttime_slot_id

fromtime_slot))

thendelete fromsection

where time_slot_id =NEW.time_slot_id;

end if;

end

48304ba5e6f9fe08f3fa1abda7d326ab.png

iii.  在time_slot表上定义一个DELETE触发器,当删除的元组的time_slot_id不在删除后的time_slot表中时,且section中存在包含这个time_slot_id 值的元组时,触发器被启动,以确保time_slot中发生删除时,section的参照完整性。

48304ba5e6f9fe08f3fa1abda7d326ab.png

delimiter

create trigger timeslot_check2 after delete

on time_slot foreach row

beginif(OLD.time_slot_id not in(selecttime_slot_id

fromtime_slot)

and OLD.time_slot_id in(selecttime_slot_id

fromsection))

theninsert intotime_slot

values(OLD);

end if;

end

48304ba5e6f9fe08f3fa1abda7d326ab.png

iv.   验证定义在takes表上的AFTER UPDATE触发器

初始时编号999的学生在493这门课成绩为F,即不通过,无法获得学分:

55e2500ede317de1d615ff782bb2ab9b.png

且其已获学分为15:

f03bf9d8dc9427e7757405735bb4ae52.png

假设补考过后其成绩为B,需更新takes:

c53106490bf8343b41457dfdefeb20a8.png

定义在takes表上的UPDATE触发器触发,此时学生的总学分应该增加:

1a8c6f18b9975449166a62278608d087.png

从上图可以看到UPDATE触发器触发成功。

(2).BEFORE触发器

Before触发器的update,insert,delete语句语法和after触发器基本类似,故此下面不再赘述全部三种语句,只拿BEFORE INSERT触发器做为例子。

i.                     在takes表上定义一个before insert触发器,插入一条记录时,假设所插入的分数的

值为空白则表明该分数发生缺失,所以定义此触发器在分数值条件满足时触发用null值代替空白。

48304ba5e6f9fe08f3fa1abda7d326ab.png

delimiter

create trigger setnull before insert

on takes foreach row

beginif(NEW.grade = ' ')

thenset NEW.grade = null;

end if;

end

48304ba5e6f9fe08f3fa1abda7d326ab.png

ii.  验证定义在takes表上的BEFORE INSERT触发器

初始时:

编号为999的学生只有一门课

94aed1fb5ae9597a70d71bfcf8b204db.png

假设该学生现在上了另一门课,插入元组,且该课程成绩缺失还没给出:

9b046db277345125c6112d3a73ced70c.png

查看该学生所上课程的信息:

e234a5ccb1f4d57a3b6264b5bf07805b.png

从上表可以看出takes表上的BEFORE INSERT触发器触发成功。

iii.  删除触发器

drop trigger setnull;

3e324f08847ece873ed479a1554c5477.png

总结:

after触发器—是在记录操纵之后触发,是先完成数据的增删改,再触发,触发的语句晚于监视的增删改操作,无法影响前面的增删改动作

before触发器—是在记录操纵之前触发,是先完成触发,再增删改,触发的语句先于监视的增删改,我们就有机会判断,修改即将发生的操作,如:我们在触发之前需要判断new值和old值的大小或关系,如果满足要求就触发,不通过就修改再触发;如:表之间定义的有外键,在删除主键时,必须要先删除外键表,这时就有先后之分,这里before相当于设置了断点,我们可以处理删除外键。

对于INSERT语句, 只有NEW是合法的;

对于DELETE语句,只有OLD才合法;

对于UPDATE语句,NEW、OLD可以同时使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值