例题
Posted Maynine丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了例题相关的知识,希望对你有一定的参考价值。
数据库完整性
一、实体完整性
1.实体完整性定义
关系模型的实体完整性
create table 中用 primary key 定义主键
例1.将Student表中的Sno属性定义为码
--在列级定义主码
create table Student(
Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
Ssex CHAR(2), Sage SMALLINT,
Sdept CHAR(20)
);
/*在表级定义主码
create table Student
Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2), Sage SMALLINT,
Sdept CHAR(20),
primary key(Sno)
;
*/
例3.将SC表中的Sno,Cno属性组定义为码 CREATE TABLE SC
create table sc(
Sno char(9) not NULL,
Cno char(4) not NULL,
Grade smallint,
primary key(Sno,Cno)
);
二、参照完整性
在create table 中用foreign key短语定义哪些列为外码,用references短语指明这些外码参照哪些表的主码
1.定义实体完整性
例.定义SC中的参照
create table sc
( Sno char(9) not null,
Cno char(4) not null,
Grade smallint,
primary key (Sno, Cno), /*在表级定义实体完整性*/
foreign key (Sno) references student(Sno),
/*在表级定义参照完整性*/
foreign key (Cno) references course(Cno)
/*在表级定义参照完整性*/
);
2.实体完整性检查和违约处理
create table SC
(
Sno char(9) not null,
Cno char(4) not null,
Grade smallint,
primary key (Sno,Cno),
foreign key (Sno) references student(Sno)
on delete cascade -- 级联删除SC表中相应的元组
on update cascade, --级联更新SC表中相应的元组
foreign key (Cno) references course(Cno)
on delete no action
--当删除course 表中的元组造成了与SC表不一致时拒绝删除
on update cascade
--当更新course表中的cno时,级联更新SC表中相应的元组
);
三、用户定义的完整性
用户定义的完整性是:针对某一具体应用的数据必须满足的语义要求
1.属性上的约束条件
CREATE TABLE时定义属性上的约束条件
①列值非空(NOT NULL)
②列值唯一(UNIQUE)
③检查列值是否满足一个条件表达式(CHECK)
例1.不允许取空值
CREATE TABLE SC (Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT NOT NULL,
PRIMARY KEY (Sno, Cno), …
/*如果在表级定义实体完整性,隐含了Sno,Cno不允许取空值,则在 列级不允许取空值的定义可以不写 */
);
(2)列值唯一
例2.建立部门表DEPT,要求部门名称Dname列取值唯一,部门编号Deptno列为主码
CREATE TABLE DEPT ( Deptno NUMERIC(2),
Dname CHAR(9) UNIQUE NOT NULL,
/*要求Dname列值唯一, 并且不能取空值*/
Location CHAR(10), PRIMARY KEY (Deptno)
);
(3)用CHECK短语指定列值应该满足的条件
例3.Student表的Ssex只允许取“男”或“女”。
CREATE TABLE Student
(
Sno CHAR(9) PRIMARY KEY,--列级完整性约束条件,Sno是主码
Sname CHAR(20) NOT NULL,/* Sname取唯一值*/
Ssex CHAR(2) CHECK(Ssex IN('男','女')),
Sage SMALLINT,
Sdept CHAR(20)
);
例4.SC表的Grade的值应该在0和100之间
DROP TABLE IF EXISTS SC
(
CREATE TABLE Student
(
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT CHECK(Grade>=0 AND Grade<=100),--Grade取值范围是0到100
PRIMARY KEY (Sno,Cno), FOREIGN KEY (Sno) REFERENCES Student(Sno),
FOREIGN KEY (Cno)REFERENCES Course(Cno)
);
);
2.元组上的约束条件
1.元组上约束条件的定义
在CREATE TABLE时可以用CHECK短语定义元组上的约束条件,即元组级的限制
CREATE TABLE Student
(
Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2) ,
Sage SMALLINT,
Sdept CHAR(20)
PRIMARY KEY(Sno),
CHECK(Ssex='女'OR Sname NOT LIKE 'Ms.%')
);
性别是女性的元组都能通过该项检查,因为Ssex=‘女’成立;
当性别是男性时,要通过检查则名字一定不能以Ms.打头
2.元组上的约束条件检查和违约处理
插入元组或修改属性的值时,关系数据库管理系统检查元组上的约束条件是否被满足
如果不满足则操作被拒绝执行
四、完整性约束命名子句
1.完整性约束命名子句
CONSTRAINT <完整性约束条件名><完整性约束条件>
/*<完整性约束条件>包括NOT NULL、UNIQUE、
PRIMARY KEY短语、FOREIGN KEY短语、CHECK*/
例1.建立学生登记表Student,要求学号在90000~99999之间,姓名不能取空值,年龄小于30,性别只能是“男”或“女”。
CREATE TABLE Student
( Sno NUMERIC(6)
CONSTRAINT C1 CHECK(Sno BETWEEN 90000 AND 99999),
Sname CHAR(20)
CONSTRAINT C2 NOT NULL,
Sage NUMERIC(3)
CONSTRAINT C3 CHECK(Sage<30),
Ssex CHAR(2)
CONSTRAINT C4 CHECK(Ssex IN('男','女')),
CONSTRAINT StudentKey PRIMARY KEY(Sno),
)
例2.建立教师表TEACHER,要求每个教师的应发工资不低于3000元。应发工资是工资列Sal与扣除项Deduct之和。
CREATE TABLE TEACHER
(Eno NUMERIC(4) PRIMARY KEY,
Ename CHAR(10),
Job CHAR(8),
Sal NUMERIC(7,2),
Deduct NUMERIC(7,2),
Deptno NUMERIC(2),
CONSTRAINT TEACHERFKey FOREIGN KEY (Deptno)
REFERENCES DEPT(Deptno),
CONSTRAINT C1 CHECK (Sal + Deduct >= 3000)
)
2.修改表中的完整性限制
使用ALTER TABLE语句修改表中的完整性限制
例3.去掉例5.10 Student表中对性别的限制。
ALTER TABLE Student
DROP CONSTRAINT C4;
例4.修改表Student中的约束条件,要求学号改为在900000~999999之间,年龄由小于30改为小于40
ALTER TABLE Student
DROP CONSTRAINT C1;
ALTER TABLE Student
ADD CONSTRAINT C1 CHECK (Sno BETWEEN 900000 AND 999999);
ALTER TABLE Student
DROP CONSTRAINT C3;
ALTER TABLE Student
ADD CONSTRAINT C3 CHECK(Sage<40);
六、断言
SQL中,可以使用 CREATE ASSERTION语句, 通过声明性断言来指定更具一般性的约束。
- 可以定义比较复杂的完整性约束。
- 断言创建以后,任何对断言中所涉及的关系的操作都会触发DBMS对断言的检查,任何使断言不为真值的操作都会被拒绝执行
1.创建断言的语句格式
CREATE ASSERTION<断言名><CHECK 子句>
每个断言都被赋予一个名字,<CHECK 子句>中的约束条件与WHERE子句的条件表达式类似。
例1.限制数据库课程最多60名学生选修
CREATE ASSERTION ASSE_SC_CNUM1
CHECK(60>=ALL(SELECT count(*)
FROM Course,SC
WHERE SC.Cno=Course.Cno and Course.Cname='数据库')
);
例2.限制每一门课程最多60名学生选修
CREATE ASSERTION ASSE_SC_CNUM1
CHECK(60>=ALL(SELECT count(*)
FROM SC
GROUP BY cno)
);
删除断言的语句格式为:
DROP ASSERTION <断言名>;
问题总结
我们的SQLserver又双叒叕不与我们教材的语句接轨了_(:3」∠)_
下面的是教材中的代码
CREATE ASSERTION ASSE_SC_DB_NUM
CHECK(60>=(SELECT COUNT(*)
FROM Course,SC WHERE SC.Cno=Course.Cno AND Course.Cname=’数据库’)
);
然而,在SQL server中没有ASSERTION这一关键字,所以要另寻他法,要用触发器的方式来实现,语句格式为
CREATE TRIGGER <触发器名> ON <表名> FOR <触发事件> AS <触发动作体>
触发事件可以是INSERT、DELETE或UPDATE,也可以是几个事件的组合。
触发动作体可以简单理解为触发条件为真时进行的动作,执行的SQL块。
我们可以原有的SQL语句通过触发器来改成TSQL语句
--创建insert插入类型触发器
IF (OBJECT_ID('TGR_SC_INSERT', 'TR') IS NOT NULL) -- 如果已经存在该触发器,就删除
DROP TRIGGER TGR_SC_INSERT
GO
CREATE TRIGGER TGR_SC_INSERT
ON SC
FOR INSERT --插入触发
AS
-- 定义变量,DECLARE声明(declare)
-- @COUNT存储已经选择数据库课程的学生数量;@Sno学号;@Cno课程号;@Grade课程成绩
DECLARE @COUNT INT,@Sno CHAR(9),@Cno CHAR(4), @Grade SMALLINT;
-- 查询已经选择“数据库”课程的学生的数量,并赋值给@COUNT
SELECT @COUNT=COUNT(*) FROM Course,SC WHERE SC.Cno=Course.Cno AND Course.Cname='数据库';
-- 在INSERTED中查询已经插入的记录信息,即触发触发器的INSERT语句所插入的记录信息
SELECT @Sno=Sno,@Cno=Cno,@Grade=Grade FROM INSERTED; -- inserted
IF(@COUNT>3) -- 在插入语句后,如果选修“数据库”课程的学生数量超过三人,就删除插入的信息
BEGIN
DELETE SC WHERE Sno=@Sno AND Cno=@Cno AND Grade=@Grade;
END
GO
上面这部分是借鉴的大佬的,欢迎去原文章点赞
SQL server中实现断言
https://blog.csdn.net/weixin_43808478/article/details/105709686
以上是关于例题的主要内容,如果未能解决你的问题,请参考以下文章