总结一下,数据库完整性约束几个列子
CreateTable有三种功能:定义关系模式、定义完整性约束和定义物理存储特性
定义完整性约束条件:
示例
Create Table Student (
S# char(8) not null unique,
Sname char(10),
Ssex char(2) constraint ctssex check (Ssex=‘男’ or
Ssex=‘女’), Sage integer check (Sage>=1 and Sage<150),
D# char(2) references Dept(D#) on delete cascade,
Sclass char(6) );
//假定Ssex只能取{男,女}, 1=
示例
Create Table Course (
C# char(3) ,
Cname char(12),
Chours integer,
Credit float(1) constraint ctcredit check (Credit >=0.0 and
Credit<=5.0 ),
T# char(3) references Teacher(T#) on delete cascade );
//假定每门课学分最多5分,最少0分
示例
Create Table Student ( S# char(8) not null unique, Sname char(10),
Ssex char(2) constraint ctssex check (Ssex=‘男’ or
Ssex=‘女’), Sage integer check (Sage>1 and Sage<150),
D# char(2) references Dept(D#) on delete cascade,
Sclass char(6) ,
primary key(S#) );
Create Table Course ( C# char(3) , Cname char(12), Chours integer,
Credit float(1) constraint ctcredit check (Credit >=0.0 and
Credit<=5.0 ), T# char(3) references Teacher(T#) on delete cascade,
primary key(C#),
constraint ctcc check(Chours/Credit = 20) );
//假定严格约束20学时一个学分
示例
Create Table SC ( S# char(8), C# char(3),
Score float(1) constraint ctscore check (Score>=0.0 and
Score<=100.0),
forergn key (S#) references student(S#) on delete cascade,
forergn key (C#) references course(C#) on delete cascade );
check中的条件可以是Select-From-Where内任何Where后的语句,包含子查询。
Create Table中定义的表约束或列约束可以在以后根据需要进行撤消或追加。撤消或追加约束的语句是 Alter Table(不同系统可能有差异)
示例:撤消SC表的ctscore约束(由此可见,未命名的约束是不能撤消)
Alter Table SC
DROP CONSTRAINT ctscore;
示例:若要再对SC表的score进行约束,比如分数在0~150之间,则可新增
加一个约束。在Oracle中增加新约束,需要通过修改列的定义来完成
Alter Table SC
Modify ( Score float(1) constraint nctscore check (Score>=0.0 and
Score<=150.0) );
有些DBMS支持独立的追加约束,注意书写格式可能有些差异
示例:
Alter Table SC
Add Constraint nctscore check (Score>=0.0 and Score<=150.0) );
一个断言就是一个谓词表达式,它表达了希望数据库总能满足的条件
CREATE ASSERTION < assertion-name > CHECK < predicate >
同是静态约束的 断言ASSERTION和Create Table,区别在于,ASSERTION能实现多个表或聚集操作复杂的完整性约束,Create Table实现的单个表的操作
示例
“每个分行的贷款总量必须小于该分行所有账户的余额总和”
create assertion sum_constraint check
(not exists (select * from branch
where (select sum(amount ) from loan
where loan.branch_name =
branch.branch_name )
>= (select sum (balance ) from account
where account.branch_name =
branch.branch_name )))
account(branch_name, account_number,…, balance) //分行,账户及其余额
loan(branch_name , loan_number, amount,) //分行的每一笔贷款
branch(branch_name, … ) //分行
Trigger是一种过程完整性约束(相比之下,Create Table中定义的都是非过程性约束),是一段程序,该程序可以在特定的时刻被自动触发执行,比如在一次更新操作之前执行,或在更新操作之后执行。
触发器Trigger意义:当某一事件发生时( Before | After ),对该事件产生的结果(或是每一元组,或是整个操作的所有元组), 检查条件 search_condition ,如果满足条件,则执行后面的程序段。条件或程序段中引用的变量可用 corr_name_def 来限定。
事件:BEFORE | AFTER { INSERT | DELETE | UPDATE …}
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命别名为
}
示例一
设计一个触发器当进行Teacher表更新元组时, 使其工资只能升不能降
示例二
假设student(S#, Sname, SumCourse), SumCourse为该同学已学习课程的门数,初始值为0,以后每选修一门都要对其增1 。设计一个触发器自动完成上述功能。
示例三
假设student(S#, Sname, Sage, Ssex, Sclass)中某一学生要变更其主码S#的值,如使其原来的98030101变更为99030131, 此时sc表中该同学已选课记录的S#也需自动随其改变。设计一个触发器完成上述功能
示例四
假设student(S#, Sname, SumCourse), 当删除某一同学S#时,该同学的所有选课也都要删除。设计一个触发器完成上述功能
示例五
假设student(S#, Sname, SumCourse), 当删除某一同学S#时,该同学的所有选课中的S#都要置为空值。设计一个触发器完成上述功能
示例六
假设Dept(D#, Dname, Dean), 而Dean一定是该系教师Teacher(T#, Tname, D#, Salary)中工资最高的教师。设计一个触发器完成上述功能
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;
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;
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;
create trigger delS# after delete on Student
referencing old oldi
for each row
begin
delete from sc where S# = :oldi.S# ;
end;
create trigger delS# after delete on Student
referencing old oldi
for each row
begin
update sc set S# = Null where S# = :oldi.S# ;
end;
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;