数据库系统概论中SQL语句

文章目录

(一) 创建教材学生-课程数据库

注意注意!本文使用MySQL数据库,其中database和schema是同意义。

create database s_c;
use s_c;

1.建立 Student表

CREATE TABLE Student (
    Sno CHAR(9) PRIMARY KEY,
    Sname CHAR(20) UNIQUE,
    Ssex CHAR(2),
    Sage SMALLINT,
    Sdept CHAR(20)
);

2.建立Course表

CREATE TABLE Course (
    Cno CHAR(4) PRIMARY KEY,
    Cname CHAR(40),
    Cpno CHAR(4),
    Ccredit SMALLINT,
    FOREIGN KEY (Cpno) REFERENCES Course (Cno)
);

3.建立SC表

CREATE TABLE SC (
    Sno CHAR(9),
    Cno CHAR(4),
    Grade SMALLINT,
    PRIMARY KEY (Sno , Cno),
    FOREIGN KEY (Sno)  REFERENCES Student (Sno),
    FOREIGN KEY (Cno)  REFERENCES Course (Cno)
);

修改基本表

  • [例1] 向Student表增加“入学时间”列,其数据类型为日期型。
ALTER TABLE Student ADD S_entrance DATE;
  • [例2] 将年龄的数据类型由字符型(假设原来的数据类型是字符型)改为整数。
ALTER TABLE Student ALTER COLUMN Sage INT;
  • [例3] 增加课程名称必须取唯一值的约束条件。
ALTER TABLE Course ADD UNIQUE(Cname);

删除基本表

  • [例4] 删除Student表
DROP TABLE  Student  CASCADE ;

(二) 装载数据

1.往学生表(student)插入数据

insert into student values('200215121','李勇','男',20,'CS');
insert into student values('200215122','刘晨','女',19,'CS');
insert into student values('200215123','王敏','女',18,'MA');
insert into student values('200215125','张立','男',19,'IS');

2.往course表插入数据

insert into course values('1','数据库',null,4);
insert into course values('2','数学',null,2);
insert into course values('3','信息系统',null,4);
insert into course values('4','操作系统',null,3);
insert into course values('5','数据结构',null,4);
insert into course values('6','数据处理',null,2);
insert into course values('7','PASCAL语言',null,4);
update course set cpno='5' where cno='1';
update course set cpno='1' where cno='3';
update course set cpno='6' where cno='4';
update course set cpno='7' where cno='5';
update course set cpno='6' where cno='7';
select * from course;

3.往sc表插入数据

insert into sc values('200215121','1',92);
insert into sc values('200215121','2',85);
insert into sc values('200215121','3',88);
insert into sc values('200215122','2',90);
insert into sc values('200215122','3',80);
select * from sc;

(三) 数据查询

单表查询

1. 选择表中的若干列

(1)查询指定列
  • [例1] 查询全体学生的学号与姓名。
SELECT Sno,Sname 
FROM Student
  • [例2] 查询全体学生的姓名、学号、所在系。
SELECT Sname,Sno,Sdept 
FROM Student
(2)查询全部列
  • [例3] 查询全体学生的详细记录。
SELECT  Sno,Sname,Ssex,Sage,Sdept
FROM Student

SELECT * FROM Student
(3)查询经过计算的值
  • [例4] 查全体学生的姓名及其出生年份。
SELECT Sname, 2014-Sage    
FROM Student 
  • [例5] 查询全体学生的姓名、出生年份和所有系,要求用小写字母表示所有系名
SELECT Sname,'Year of Birth: ',2014-Sage birth_year,LOWER(Sdept)
FROM Student
  • 使用列别名改变查询结果的列标题:
SELECT Sname NAME,
       'Year of Birth:' BIRTH,
       2014-Sage  BIRTHDAY,
       LOWER(Sdept) DEPARTMENT
FROM Student

2.选择表中的若干元组

(1)消除取值重复的行
  • 指定DISTINCT关键词,去掉表中重复的行
SELECT DISTINCT Sno
FROM SC
(2)查询满足条件的元组
比较大小
  • [例7] 查询计算机科学系全体学生的名单。
SELECT Sname
FROM Student
WHERE Sdept='CS' 
  • [例8] 查询所有年龄在20岁以下的学生姓名及其年龄。
SELECT Sname,Sage
FROM  Student   
WHERE Sage < 20
  • [例9] 查询考试成绩有不及格的学生的学号。
SELECT DISTINCT Sno
FROM  SC
WHERE Grade<60
确定范围
  • [例10] 查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM    Student
WHERE   Sage BETWEEN 20 AND 23
  • [例11] 查询年龄不在20~23岁之间的学生姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM    Student
WHERE Sage NOT BETWEEN 20 AND 23
确定集合
  • [例12]查询信息系(IS)、数学系(MA)和计算机科学系(CS)学生的姓名和性别。
SELECT Sname,Ssex
FROM  Student
WHERE Sdept IN ( 'IS','MA','CS' );
  • [例13]查询既不是信息系、数学系,也不是计算机科学系的学生的姓名和性别。
SELECT Sname,Ssex
FROM Student
WHERE Sdept NOT IN ( 'IS','MA','CS' )
字符匹配
  • [例14] 查询学号为200215121的学生的详细情况。
SELECT *   
FROM  Student 
WHERE  Sno LIKE '200215121'
  • [例15] 查询所有姓刘学生的姓名、学号和性别。
SELECT Sname,Sno,Ssex    
FROM Student     
WHERE  Sname LIKE '李%'
  • [例16] 查询姓"欧阳"且全名为三个汉字的学生的姓名。
SELECT Sname     
FROM   Student      
WHERE  Sname LIKE '欧阳__'

–[例17] 查询名字中第2个字为"阳"字的学生的姓名和学号。

SELECT Sname,Sno     
FROM Student    
WHERE Sname LIKE '__阳%'
  • [例18] 查询所有不姓刘的学生姓名。
SELECT Sname,Sno,Ssex    
FROM Student   
WHERE Sname NOT LIKE '刘%'
  • [例19] 查询DB_Design课程的课程号和学分。
SELECT Cno,Ccredit     
FROM Course     
WHERE Cname LIKE 'DB\_Design' ESCAPE '\'
  • [例20] 查询以"DB_"开头,且倒数第3个字符为 i的课程的详细情况。
SELECT  *   
FROM   Course     
WHERE  Cname LIKE  'DB\_%i_ _' ESCAPE '\'
涉及空值的查询
  • [例21] 某些学生选修课程后没有参加考试,所以有选课记录,但没有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
SELECT Sno,Cno     
FROM  SC     
WHERE  Grade IS NULL
  • [例22] 查所有有成绩的学生学号和课程号。
SELECT Sno,Cno     
FROM  SC     
WHERE  Grade IS NOT NULL
多重条件查询
  • [例23] 查询计算机系年龄在20岁以下的学生姓名。
SELECT Sname     
FROM  Student     
WHERE Sdept= 'CS' AND Sage<20

3.ORDER BY子句

  • [例24] 查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。
SELECT Sno,Grade        
FROM  SC        
WHERE  Cno= ' 3 '       
ORDER BY Grade DESC
  • [例25] 查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT  *       
FROM  Student       
ORDER BY Sdept ASC,Sage DESC

4.聚焦函数

COUNT()
  • [例26] 查询学生总人数。
SELECT COUNT( * )
FROM Student
  • [例27] 查询选修了课程的学生人数。
SELECT COUNT(DISTINCT Sno)   
FROM SC
AVG()
  • [例28] 计算1号课程的学生平均成绩。
SELECT AVG(Grade)       
FROM SC         
WHERE Cno='1'
MAX()
  • [例29] 查询选修1号课程的学生最高分数。
SELECT MAX(Grade)   
FROM SC   
WHERE Cno='1'
SUM()
  • [例30] 查询学生200215121选修课程的总学分数。
SELECT SUM(Ccredit)       
FROM  SC, Course         
WHERE Sno='200215121' AND SC.Cno=Course.Cno

5.GROUP BY子句

  • [例31] 求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno)   
FROM    SC   
GROUP BY Cno
  • [例32] 查询选修了3门以上课程的学生学号。
SELECT Sno   
FROM  SC    
GROUP BY Sno   
HAVING  COUNT(*) >3

连接查询

若一个查询同时涉及两个以上的表,则称之为连接查询

1.等值查询与非等值查询

  • [例33] 查询每个学生及其选修课程的情况
SELECT  Student.*,SC.*
FROM     Student,SC
WHERE  Student.Sno = SC.Sno
  • [例34] 对[例33]用自然连接完成。
SELECT  Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM     Student,SC  
WHERE  Student.Sno = SC.Sno
  • [例35]查询选修2号课程且成绩在90分以上的所有学生
SELECT 
    Student.Sno, Sname
FROM
    Student,
    SC
WHERE
    Student.Sno = SC.Sno AND SC.Cno = '2'
        AND SC.Grade > 90

2.自身连接

  • [例36]查询每一门课的间接先修课(即先修课的先修课)
SELECT  FIRST.Cno,SECOND.Cpno    
FROM  Course  FIRST,Course  SECOND  
WHERE FIRST.Cpno = SECOND.Cno

3.外连接

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM  Student  
LEFT OUT JOIN SC 
ON (Student.Sno=SC.Sno)

4.多表连接

  • [例38]查询每个学生的学号、姓名、选修的课程名及成绩
SELECT 
    Student.Sno, Sname, Cname, Grade
FROM
    Student,
    SC,
    Course
WHERE
    Student.Sno = SC.Sno
        AND SC.Cno = Course.Cno

嵌套查询

1.带有IN谓词的子查询

  • [例39] 查询与“刘晨”在同一个系学习的学生。
SELECT 
    Sno, Sname, Sdept
FROM
    Student
WHERE
    Sdept IN 
    	(SELECT 
            Sdept
         FROM
            Student
         WHERE
            Sname = '刘晨')
  • [例40]查询选修了课程名为“信息系统”的学生学号和姓名
SELECT 
    Sno, Sname
FROM
    Student
WHERE
    Sno IN 
    	(SELECT 
            Sno
         FROM
            SC
         WHERE
            Cno IN 
            	(SELECT 
                    Cno
                 FROM
                    Course
                 WHERE
                    Cname = '信息系统'))

2.带有比较运算符的子查询

  • [例41] 找出每个学生超过他选修课程平均成绩的课程号。
SELECT 
    Sno, Cno
FROM
    SC x
WHERE
    Grade >= (SELECT 
            AVG(Grade)
        FROM
            SC y
        WHERE
            y.Sno = x.Sno)

3.带有ANY(SOME)或ALL谓词的子查询

  • [例42] 查询其他系中比计算机科学某一学生年龄小的学生姓名和年龄
SELECT 
    Sname, Sage
FROM
    Student
WHERE
    Sage < ANY (SELECT 
            Sage
        FROM
            Student
        WHERE
            Sdept = 'CS')
        AND Sdept <> 'CS'

  • [例43] 查询其他系中比计算机科学系所有学生年龄都小的学生姓名及年龄。
SELECT 
    Sname, Sage
FROM
    Student
WHERE
    Sage < ALL (SELECT 
            Sage
        FROM
            Student
        WHERE
            Sdept = ' CS ')
        AND Sdept <> ' CS '

4.带有EXISTS谓词的子查询

  • [例44]查询所有选修了1号课程的学生姓名。
  1. 用嵌套查询
SELECT 
    Sname
FROM
    Student
WHERE
    EXISTS( SELECT 
            *
        FROM
            SC
        WHERE
            Sno = Student.Sno AND Cno = ' 1 ')
  1. 用连接运算
SELECT Sname  
FROM Student, SC
WHERE Student.Sno=SC.Sno AND SC.Cno= '1'
  • [例45] 查询没有选修1号课程的学生姓名。
SELECT 
    Sname
FROM
    Student
WHERE
    NOT EXISTS( SELECT 
            *
        FROM
            SC
        WHERE
            Sno = Student.Sno AND Cno = '1')
  • [例46] 查询选修了全部课程的学生姓名。
SELECT 
    Sname
FROM
    Student
WHERE
    NOT EXISTS
    (SELECT 
      *
     FROM
      Course
     WHERE
         NOT EXISTS
         (SELECT 
           *
          FROM
           SC
          WHERE
           Sno = Student.Sno AND Cno = Course.Cno)
     );
  • [例47]查询至少选修了学生200215122选修的全部课程的学生号码。
SELECT DISTINCT
    Sno
FROM
    SC SCX
WHERE
    NOT EXISTS
    (SELECT 
      *
     FROM
      SC SCY
     WHERE
      SCY.Sno = ' 200215122' AND NOT EXISTS
      							 (SELECT 
                                   *
                				  FROM
                    			   SC SCZ
                				  WHERE
                    			   SCZ.Sno = SCX.Sno AND SCZ.Cno = SCY.Cno)
      )

集合查询

  • [例48] 查询计算机科学系的学生及年龄不大于19岁的学生。
    方法一:
SELECT 
    *
FROM
    Student
WHERE
    Sdept = 'CS' 
UNION 
SELECT 
    *
FROM
    Student
WHERE
    Sage <= 19

方法二:

SELECT  
DISTINCT  *     
FROM Student       
WHERE Sdept= 'CS'  OR  Sage<=19
  • [例49] 查询选修了课程1或者选修了课程2的学生。
SELECT 
    Sno
FROM
    SC
WHERE
    Cno = ' 1 ' 
UNION 
SELECT 
    Sno
FROM
    SC
WHERE
    Cno = ' 2 '
  • [例50] 查询计算机科学系的学生与年龄不大于19岁的学生的交集
SELECT 
 	*
FROM 
 	Student
WHERE 
	Sdept='CS'
INTERSECT
SELECT 
	*
FROM 
	Student
WHERE 
	Sage<=19
  • [例51] 查询选修课程1的学生集合与选修课程2的学生集合的交集
SELECT Sno  
FROM SC
WHERE Cno='1'  
INTERSECT
SELECT Sno  
FROM SC    
WHERE Cno='2'
  • [例52] 查询计算机科学系的学生与年龄不大于19岁的学生的差集。
SELECT *  

FROM Student    

WHERE Sdept='CS' 
   
EXCEPT 
    
SELECT  *   
 
FROM Student 
 
WHERE Sage <=19
SELECT 
    *
FROM
    Student s1
WHERE
    s1.Sdept = 'CS'
        AND NOT EXISTS( SELECT 
            *
        FROM
            Student s2
        WHERE
            s2.Sage <= 19 AND s1.sno = s2.sno)

基于派生表的查询

(四) 数据更新

插入数据

1.插入元组

  • [例1] 将一个新学生元组(学号:200215128;姓名:陈冬;性别:男;所在系:IS;年龄:18岁)插入到Student表中。
INSERT
INTO  Student (Sno,Sname,Ssex,Sdept,Sage)
VALUES ('200215128''陈冬''男''IS'18)
  • [例2] 将学生张成民的信息插入到Student表中。
INSERT
INTO  Student
VALUES ('200215126', '张成民', '男',18,'CS'); 
  • [例3] 插入一条选课记录( ‘200215128’,'1 ')。
INSERT
INTO SC(Sno,Cno)			//RDBMS将在新插入记录的Grade列上自动地赋空值
VALUES ('200215128','1');
INSERT
INTO SC
VALUES ('200215128','1',NULL);

2.插入子查询结果

  • [例4] 对每一个系,求学生的平均年龄,并把结果存入数据库。
CREATE  TABLE  Dept_age(
Sdept  CHAR(15),      	  /* 系名*/
Avg_age SMALLINT		  /*学生平均年龄*/
);   	 
INSERT 
INTO  Dept_age(Sdept,Avg_age)
SELECT  Sdept,AVG(Sage)
FROM  Student
GROUP BY Sdept;

修改数据

1.修改某一个元组的值

  • [例5] 将学生201215121的年龄改为22岁
UPDATE  Student
SET Sage=22
WHERE  Sno='201215121'; 

2.修改多个元组的值

  • [例6] 将所有学生的年龄增加1岁
UPDATE Student
SET Sage= Sage+1;

3.带子查询的修改语句

  • [例7] 将计算机科学系全体学生的成绩置零。
UPDATE SC
SET  Grade=0
WHERE Sno IN
	( SELECT Sno
	  From Student
	  WHERE Sdept='CS');

删除数据

1.删除某一个元组的值

  • [例8] 删除学号为201215128的学生记录
DELETE
FROM Student
WHERE Sno= '200215128';

2.删除多个元组的值

  • [例9] 删除所有的学生选课记录。
DELETE
FROM SC;

3.带子查询的删除语句

  • [例10] 删除计算机科学系所有学生的选课记录。
DELETE
FROM SC
WHERE Sno IN
	( SELECT Sno
	  From Student
	  WHERE Sdept='CS');

(五) 视图

定义视图

1.建立视图

  • [例1] 建立信息系IS学生的视图。
CREATE VIEW IS_Student
AS 
SELECT Sno,Sname,Sage
FROM    Student
WHERE  Sdept= 'IS';
  • [例2]建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系IS的学生。
CREATE VIEW IS_Student
AS 
SELECT Sno,Sname,Sage
FROM  Student
WHERE  Sdept= 'IS'
WITH CHECK OPTION;
  • [例3] 建立信息系选修了1号课程的学生视图。
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS 
SELECT Student.Sno,Sname,Grade
FROM  Student,SC
WHERE  Sdept= 'IS' 
	   AND Student.Sno=SC.Sno 
       AND SC.Cno= '1';
  • [例4] 建立信息系选修了1号课程且成绩在90分以上的学生的视图。
CREATE VIEW IS_S2
AS
SELECT Sno,Sname,Grade
FROM  IS_S1
WHERE  Grade>=90;
  • [例5] 定义一个反映学生出生年份的视图。
CREATE  VIEW BT_S(Sno,Sname,Sbirth)
AS 
SELECT Sno,Sname,2000-Sage
FROM  Student;
  • [例6] 将学生的学号及他的平均成绩定义为一个视图
CREATE  VIEW S_G(Sno,Gavg)
AS  
SELECT Sno,AVG(Grade)
FROM  SC
GROUP BY Sno;
  • [例7]将Student表中所有女生记录定义为一个视图
CREATE VIEW F_Student(F_Sno,name,sex,age,dept)
AS
SELECT *
FROM  Student
WHERE Ssex='女';

2.删除视图

  • [例8] 删除视图IS_S1
DROP VIEW IS_S1;

查询视图

  • [例9] 在信息系学生的视图中找出年龄小于等于20岁的学生。
SELECT  Sno,Sage
FROM    IS_Student
WHERE   Sage<=20;
  • [例10] 查询选修了1号课程的信息系学生
SELECT  IS_Student.Sno,Sname
FROM    IS_Student,SC
WHERE   IS_Student.Sno =SC.Sno AND SC.Cno= '1';
  • [例11]在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩
SELECT *
FROM   S_G
WHERE  Gavg>=90;

更新视图

  • [例12] 将信息系学生视图IS_Student中学号201215125的学生姓名改为“刘辰”。
UPDATE  IS_Student
SET  Sname= '刘辰'
WHERE  Sno= '201215125'; 
UPDATE  Student
SET Sname= '刘辰'
WHERE Sno= '201215125' 
AND Sdept= 'IS';
  • [例13] 向信息系学生视图IS_Student中插入一个新的学生记录:200215111,赵新,20岁
INSERT
INTO IS_Student
VALUES('200215111','赵新',20);	//插入后基本表Student字段Sdept为空,视图表IS_Student无数据
INSERT
INTO   Student(Sno,Sname,Sage,Sdept)
VALUES('200215129','赵新2',20,NULL);
  • [例14]删除信息系学生视图IS_Student中学号为200215129的记录
DELETE
FROM IS_Student
WHERE Sno= '200215129';
DELETE
FROM Student
WHERE Sno= '200215129' AND Sdept= 'IS';

(六)数据库安全性控制

授权:授予与收回

1.GRANT

  • [例1] 把查询Student表权限授给用户U1
GRANT SELECT 
ON TABLE Student 
TO U1;
  • [例2] 把对Student表和Course表的全部权限授予用户U2和U3
GRANT ALL PRIVILIGES 
ON TABLE Student, Course 
TO U2, U3;
  • [例3] 把对表SC的查询权限授予所有用户
GRANT SELECT 
ON TABLE SC 
TO PUBLIC;
  • [例4] 把查询Student表和修改学生学号的权限授给用户U4
GRANT UPDATE(Sno), SELECT 
ON TABLE Student 
TO U4;
  • [例5] 把对表SC的INSERT权限授予U5用户,并允许他再将此权限授予其他用户
GRANT INSERT 
ON TABLE SC 
TO U5
WITH GRANT OPTION;

2.REVOKE

  • [例6] 把用户U4修改学生学号的权限收回
REVOKE UPDATE(Sno)
ON TABLE Student 
FROM U4;
  • [例7] 收回所有用户对表SC的查询权限
REVOKE SELECT 
ON TABLE SC 
FROM PUBLIC;
  • [例8] 把用户U5对SC表的INSERT权限收回
REVOKE INSERT 
ON TABLE SC 
FROM U5 CASCADE ;

数据库角色

1.角色的创建

CREATE ROLE R1;

2.给角色授权

GRANT SELECTUPDATEINSERT 
ON TABLE Student 
TO R1

3.将一个角色授予其他的角色或用户

GRANT  R1 
TO 王平,张明,赵玲;

4.角色权限的收回

REVOKE  R1 
FROM 王平;

(七)数据库完整性

实体完整性

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)
); 
CREATE TABLE SC
(Sno  CHAR(9)  NOT NULL, 
 Cno  CHAR(4)  NOT NULL,  
 Grade  SMALLINTPRIMARY KEY (Sno,Cno)     /*只能在表级定义主码*/
); 

参照完整性

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)    
);
  • [例1] 显式说明参照完整性的违约处理示例
CREATE TABLE SC
(Sno   CHAR(9)  NOT NULL,
 Cno   CHAR(4)  NOT NULL,
 Grade  SMALLINTPRIMARY KEY(Sno,Cno), 				
 FOREIGN KEY (Sno) REFERENCES Student(Sno) 
 ON DELETE CASCADE    	/*级联删除SC表中相应的元组*/
 ON UPDATE CASCADE/*级联更新SC表中相应的元组*/
 
 FOREIGN KEY (Cno) REFERENCES Course(Cno) 
 /*当删除course 表中的元组造成了与SC表不一致时拒绝删除*/	                    
 ON DELETE NO ACTION 	
 /*当更新course表中的cno时,级联更新SC表中相应的元组*/
 ON UPDATE CASCADE   	 
)

用户定义的完整性

1.属性上的约束条件

  • [例2] 在定义SC表时,说明Sno、Cno、Grade属性不允许取空值
CREATE TABLE SC
(Sno  CHAR(9)  NOT NULL,	
 Cno  CHAR(4)  NOT NULL,	
 Grade  SMALLINT NOT NULLPRIMARY KEY (Sno, Cno)/*如果在表级定义实体完整性,隐含了Sno,Cno不允许取空值,则在列级不允许取空值的定义就不必写了*/;
  • [例3] 建立部门表DEPT,要求部门名称Dname列取值唯一,部门编号Deptno列为主码
CREATE TABLE DEPT
(Deptno  NUMERIC(2),
 Dname  CHAR(9)  UNIQUE/*要求Dname列值唯一*/
 Location  CHAR(10)PRIMARY KEY (Deptno)
);
  • [例4]Student表的Ssex只允许取“男”或“女”。
CREATE TABLE Student
(Sno  CHAR(9) PRIMARY KEY,
 Sname CHAR(8) NOT NULL,                     
 Ssex  CHAR(2)  CHECK (Ssex IN (‘男’,‘女’))/*性别属性Ssex只允许取'男'或'女' */               
 Sage  SMALLINT,
 Sdept  CHAR(20)
);

2.元组上的约束条件

  • [例5] 当学生的性别是男时,其名字不能以Ms.打头。
CREATE TABLE Student
(Sno    CHAR(9), 
 Sname  CHAR(8) NOT NULL,
 Ssex    CHAR(2),
 Sage   SMALLINT,
 Sdept  CHAR(20)PRIMARY KEY (Sno)CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%') 
)

完整性约束命名子句

1.设置完整性约束

  • [例6] 建立学生登记表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.修改表中的完整性限制

  • [例7] 修改表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);

断言

MySQL不支持断言

1.创建断言

  • [例8]限制数据库课程最多 60名学生选修。
CREATE ASSERTION ASSE_SC_DB_ NUM
	CHECK ( 60>=(SELECT count(*)
		  	     FROM Course,SC
			     WHERE SC.Cno=Course.Cno AND Course.Cname=数据库)
		   );
  • [例9]限制每一 门课程最多60名学生选修。
CREATE ASSERTION ASSE_SC_CNUMI
	  CHECK( 60>=ALL(SELECT count (*)
 			         FROM SC							
					 GROUP by cno)
		    );
  • [例10] 限制每个学期每一门课程最多60名学生选修
ALTER TABLE SC ADD TERM DATE;
CREATE ASSERTION ASSE_SC_CNUM2
		CHECK( 60>=ALL(select count (*) 
					   from SC 
					   group by Cno,TERM )
	          ); 

2.删除断言

DROP ASSERTION <断言名>;

触发器

1.定义触发器

在这里插入图片描述

  • [例11] 定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元”。
CREATE TRIGGER Insert_Or_Update_Sal 
BEFORE INSERT OR UPDATE ON Teacher   
/*MySQL不需要进行引用*/
FOR EACH ROW                      /*行级触发器*/
BEGIN                			  /*定义触发动作体,是PL/SQL过程块*/
	IF (new.Job='教授') AND (new.Sal < 4000) 
	THEN   new.Sal :=4000;                
    END IF;
END;       
  • [例12] 定义AFTER行级触发器,当教师表Teacher的工资发生变化后就自动在工资变化表Sal_log中增加一条相应记录
CREATE TABLE Sal_log
(Eno    NUMERIC(4)  references teacher(eno),
 Sal     NUMERIC(72),
 Username  char(10)Date   TIMESTAMP
)
CREATE TRIGGER Insert_Sal               	
AFTER INSERT ON Teacher      	/*触发事件是INSERT*/
FOR EACH ROW
BEGIN
    INSERT 
    INTO Sal_log 
    VALUES(new.Eno,new.Sal,CURRENT_USERCURRENT_TIMESTAMP);
END;
CREATE TRIGGER Update_Sal            	
AFTER UPDATE ON Teacher    	
FOR EACH ROW
BEGIN 
    IF (new.Sal <> old.Sal) THEN 
    	INSERT 
    	INTO Sal_log 
    	VALUES(new.Eno,new.Sal,CURRENT_USERCURRENT_TIMESTAMP);
    END IF;
END;

2.激活触发器

3.删除触发器

DROP TRIGGER <触发器名> ON <表名>;
  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值