利用SQL语言实现数据库的动态完整性

利用SQL语言实现数据库的动态完整性

实现数据库动态完整的方法—触发器Trigger

触发器Trigger

  • Create Table中的表约束和列约束基本上都是静态的约束,也基本上都是对单一列或单一元组的约束(尽管有参照完整性),为实现动态约束以及多个元组之间的完整性约束,就需要触发器技术Trigger。

  • Trigger是一种过程完整性约束(相比之下,Create Table中定义的都是非过程性约束),是一段程序,该程序可以在特定的时刻被自动触发执行,比如在一次更新操作之前执行,或在更新操作之后执行。

  • 基本语法

CREATE TRIGGER trigger_name BEFORE | AFTER
{ INSERT | DELETE | UPDATE [OF colname {, colname...}] }
ON tablename [REFERENCING corr_name_def {, corr_name_def...} ]
[FOR EACH ROW | FOR EACH STATEMENT]
//对更新操作的每一条结果(前者),或整个更新操作完成(后者) [WHEN (search_condition)] //检查条件,如满足执行下述程序
{ statement //单行程序直接书写,多行程序要用下行方式
| BEGIN ATOMIC statement; { statement;...} END }
  • 触发器Trigger意义:当某一事件发生时(Before|After),对该事件产生的结果(或是每一元组,或是整个操作的所有元组), 检查条件search_condition,如果满足条件,则执行后面的程序段。条件或程序段中引用的变量可用corr_name_def来限定。

  • 事件:BEFORE | AFTER { INSERT | DELETE | UPDATE …}

    • 当一个事件(Insert, Delete, 或Update)发生之前Before或发生之后After触发。

    • 操作发生,执行触发器操作需处理两组值:更新前的值和更新后的值,这两个值由corr_name_def的使用来区分。
      在这里插入图片描述

  • corr_name_def的定义。

{ OLD [ROW] [AS] old_row_corr_name //更新前的旧元组命别名为
| NEW [ROW] [AS] new_row_corr_name //更新后的新元组命别名为
| OLD TABLE [AS] old_table_corr_name //更新前的旧Table命别名为
| NEW TABLE [AS] new_table_corr_name //更新后的新Table命别名为
}
  • corr_name_def将在检测条件或后面的动作程序段中被引用处理。
    在这里插入图片描述

触发器Trigger示例

示例一

设计一个触发器当进行Teacher表更新元组时, 使其工资只能升不能降。

create trigger teacher_chgsal before update of salary
on teacher
referencing new x, old y
for each row when (x.salary < y.salary)
begin
raise_application_error(-20003, 'invalid salary on update'); 
//此条语句为Oracle的错误处理函数
end;
Integrity Constraint ::= ( O,P,A,R)

示例二

假设student(S#, Sname, SumCourse), SumCourse为该同学已学习课程的门数,初始值为0,以后每选修一门都要对其增1 。设计一个触发器自动完成上述功能。

create trigger sumc after insert on sc
referencing new row newi
for each row
begin
update student set SumCourse = SumCourse + 1
where S# = :newi.S# ; 
end;
Integrity Constraint ::= ( O,P,A,R)

示例三

假设student(S#, Sname, Sage, Ssex, Sclass)中某一学生要变更其主码S#的值,如使其原来的98030101变更为99030131, 此时sc表中该同学已选课记录的S#也需自动随其改变。设计一个触发器完成上述功能。

create trigger updS# after update of S# on student
referencing old oldi, new newi
for each row 
begin
update sc set S# = newi.S# where S# = :oldi.S# ;
end;
Integrity Constraint ::= ( O,P,A,R)

示例四

假设student(S#, Sname, SumCourse), 当删除某一同学S#时,该同学的所有选课也都要删除。设计一个触发器完成上述功能。

create trigger delS# after delete on Student
referencing old oldi
for each row 
begin
delete sc where S# = :oldi.S# ;
end;
Integrity Constraint ::= ( O,P,A,R)

示例五

假设student(S#, Sname, SumCourse), 当删除某一同学S#时,该同学的所有选课中的S#都要置为空值。设计一个触发器完成上述功能。

create trigger delS# after delete on Student
referencing old oldi
for each row 
begin
update sc set S# = Null where S# = :oldi.S# ;
end;
Integrity Constraint ::= ( O,P,A,R)

示例六

假设Dept(D#, Dname, Dean), 而Dean一定是该系教师Teacher(T#, Tname, D#, Salary)中工资最高的教师。设计一个触发器完成上述功能。

create trigger upddean before update of Dean on Dept 
referencing old oldi, new newi
for each row when ( dean not in 
(select Tname from Teacher where D# = :newi.D# 
and salary >=
all (select salary from Teacher where D# = :newi.D#))
begin
raise_application_error(-20003, 'invalid Dean on update'); 
end;
Integrity Constraint ::= ( O,P,A,R)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值