当前位置:文档之家› 数据库原理 第3章 完整性约束

数据库原理 第3章 完整性约束


<( select count( * ) from teacher )*0.6 )
断言是不与任何一个表相联系的约束。
3) 定义触发器(Trigger) 触发器是一种特殊的存储过程,它在插入、删 除、修改特定表中的数据时,触发执行(由DBMS
自动调用)。它能提供比数据库本身标准功能更精
细、更复杂的数据控制能力。可用于数据库的安全 性控制和完整性检查。 请看下页范例:
器。
触发器的功能 触发器对于强制执行的工作是非常有用的,
它主要用于下面两种情况:
1、保证数据的完整性和一致性。当规则太复
杂,不能用数据定义语言(DDL)定义它们、这时使
用触发器非常有效;
2、实现数据之间逻辑联系的业务规则。
例如:在职工表中插入一个新的职工记录时,业务规 则要求职工的工作终止日期字段是一个空值。这个规则不
create table Teacher( Tno integer Primary Key, Tname char(6) not null, Title char(6), Dept char(10)); insert into Teacher values (101,'李华','讲师','计算机');
时触发; ● 删除触发器 (Delete trigger),在表中企图删除记录 时触发; ● 修改触发器 (Update trigger),在表中企图修改记录 时触发。
触发器的其他用途
触发器的许多使用都超出了完整性维护的范围。例如,
希望知道一个发出订单的顾客是否在上月进行了足够的交
易以至满足了公司规定的打折条件。如果是这样,业务员 必须被告之,从而通知顾客,以便达到促销的目的。 触发器能够产生事件的日志,同时支持审计和安全检 查。
create Table Course( Cno integer not null, Tno integer not null, Cname char(10) not null, credit numeric(3,1) not null, Primary key(cno,tno)); insert into Course values(1,101,'数据库',3.5);
触发器和存储过程
当对一个表执行特定的操作时,被调用或者被‚触发‛
的SQL语句称为触发器。触发器能够依次调用SQL语句或 者存储过程。 触发器是事件驱动的SQL代码,当插入、删除、修改 指定的表和列中的数据时,这些代码将自动执行,因此触 发器总是与特定的数据库表及特定的数据库事件(如插入 (Insert)、删除(Delete)、修改(Update)等)相联系。
能使用数据定义语言中CREATE TABLE语句定义,它需要
一个触发器。 对于不能由其它手段实现的规则可考虑使用触发器, 以此改善系统的效率。如:参照完整性、表或列的约束等。
触发器的类型
触发器是根据所触发事件的类型进行分类的。通常的
RDBMS支持三种类型的触发器: ● 插入触发器 (lnsent trigger),在表中企图插入记录
触发器的优点
触发器不依赖于任何客户端应用程序,也不依赖于
访问数据库的语言。触发器有如下优点:
1、标准化。在整个应用上,触发器保证了数据的完整 性和一致性,一旦在表上建立了触发器,它就存储在数据 库中;这种方法消除了各个客户应用程序的冗余编码,便 于规则发生变化时对编码进行修改;
2、高效率。触发器初始执行后,作为编译的代码执行。 它的运行速度快,与在客户工作站上执行这些代码相比, 在服务器上执行这些代码减少了网络通讯量和网络冲突; 触发器把数据完整性代码放在服务器平台上比放在客户工 作站上更有效; 3、安全性。触发器运行要有表主人的授权,但是,触 发器能够被在表中插入、删除、修改记录的任何一个用户 触发。任何一个应用程序或交互式子用户都无法避开触发
create table Teacher( Tno integer Primary Key, Tname char(6) not null, Title char(6), Dept char(10));
问题:每学期上课教师的人数不高于教师总数的60%
Create assertion sum-constraint check ( ( select count(distinct Tno) from course )
FOREIGN KEY 约束 用来约束两个表间的关系(也称引用完整性约束) 医生记录 唯一性约束 编号 姓名 年龄 职称 病员记录 编号 姓名 主治医生姓名
外键
注意:Oracle/SQL Server规定,外键只能引用在引用表 中Primary Key或Unique约束的列。
2、DBMS中的完整性约束实现机制
定义存储过程1(无参数传递) Create or replace Procedure Pro_demo1 as begin delete from teacher; end; 调用存储过程 execute Pro_demo1;
定义存储过程2 (有参数传递)
Create or replace Procedure Pro_demo2( v_tno in number,v_title in varchar) as Begin update teacher set title=v_title where tno=v_tno; end;
2) 断言(Assertion) 一个断言就是一个谓词,表达了我们希望数 据库总能满足的一个条件。 请看下页示例:
create Table Course( Cno integer not null, Tno integer not null, Cname char(10) not null, credit numeric(3,1) not null, Primary key(cno,tno));
大区别在于它是预先编译好的,因此存储过程的执行较快。
2、改善了安全性。 存储过程简化了安全机制,它可以简化对某些操作的授 权。
3、减少了网络通讯量。 在客户/服务器环境下,存储过程经过编译和优化后, 存储在服务器端而不是客户端。 这样,在网络上传输的只 是一个远程调用和最终的执行结果,而不是一系列的SQL语
远程服务器上的存储过程。
5、提高了开发者的劳动生产率。
存储过程消除了开发者为一个事务或一个运算法则的 多次需求而编写和测试SQL语句的重复劳动。调用一个存
储过程比写SQL语句更快、更简单。
6、有利于专门技术的使用。 技术熟练的开发者能够集中精力,写出复杂查询、运 算法则和事务的存储过程。其它具有一般SQL经验的开发 者能够调用这些存储过程。
SQL中的完整性约束
完整性约束的目的是保证用户对数据库进行修
改时不会破坏数据的一致性(防止对数据的意外破
坏)。
注意:数据的完整性与安全性的概念区别。前者是为了防 止数据库中存在不符合语义的数据(防止数据垃圾),后
者是防止对数据的非法存取。
DBMS的完整性约束
数据库的完整性是指数据的正确性和相容性。 DBMS必须提供一些功能来保证数据库中数据的 完整性,也称其为完整性检查,即提供一定的机制 来检查数据库中的数据是否满足规定的条件(称为 完整性约束条件)。
Tno Title Dept
教师编号 姓名 职称 ຫໍສະໝຸດ 门TnameCno
Tno Credit
课程编号
教师编号 课程名称 学分
Cname
在Teacher表上定义一个删除触发器 create trigger trig_demo1 after delete on teacher for each row begin delete course where course.tno=:old.tno; end;
1) 定义表的约束条件 SQL> create table demo ( tno number(4,0) primary key, tname char(8) not null, sex char(2) check(sex in (‘男’,‘女’)), salary number(6,2) default(0), tcode number(4,0) unique, dept varchar2(200) );
调用存储过程
execute Pro_demo2(101,'教授');
例如,一个用户不希望别人在他的表上使 存储过程的设臵大大提高了SQL语句的功能、效率和灵 用SELECT语句,他可以写一个仅可以修 改这个表的某些行或列的存储过程,然后 活性,具体表现在: 将调用该过程的权限授给特定的用户,这 1、改善了性能。 样其它用户就可以通过该存储过程访问这 存储过程与原始SQL语句或批处理中的SQL语句的最 个表。
Oracle 9i
create trigger trig_demo2 on teacher for update as if update(Tno) begin Declare @old_Tno integer,@new_Tno integer select @old_Tno=Tno from deleted; select @new_Tno=Tno from inserted; update course SQL Server set course.Tno=@new_Tno where course.Tno=@old_Tno; end;
7、简化了应用的维护,增加了应用的灵活性。
存储过程有助于从应用逻辑中把业务规则分离出来。 当业务发生变化,需要修改业务规则时,这个变化只影响 存储过程。与改变、测试和调整一个及多个客户的成千上 万个用户程序相比,改变和测试存储过程是更有效、更省
create table father_t ( Cno integer primary key, Cname char(10) not null, Credit numeric(3,1) );
相关主题