这次作业需要用到三张表,先把这三张表建立出来
CREATE TABLE Student /*建学生表*/
(
Sno CHAR(9) PRIMARY KEY, /*列级完整性约束条件,Sno是主码*/
Sname CHAR(20) UNIQUE, /*Sname取唯一值*/
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);
CREATE TABLE Course /*建课程表*/
(
Cno CHAR(4) PRIMARY KEY,
Cname CHAR(40),
Cpno CHAR(4),
Ccredit SMALLINT,
FOREIGN KEY(Cpno) REFERENCES Course(Cno) /*表级完整性的约束条件,Cpno是外码,被参照表是本身*/
);
CREATE TABLE SC /*建选课表*/
(
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY (Sno,Cno), /*主码由两个属性构成,必须作为表级完整性进行定义*/
FOREIGN KEY (Sno) REFERENCES Student(Sno), /*表级完整性约束条件,Sno是外码,被参照表是Student*/
FOREIGN KEY (Cno) REFERENCES Course(Cno), /*表级完整性约束条件,Cno是外码,被参照表是Course*/
);
INDEX:
【例3.13】为学生-课程数据库中的Student、Course和SC三个表建立索引。其中Student表按学号升序建唯一索引,Course表按课程号升序建唯一索引,SC表按学号升序和课程号降序建唯一索引。
CREATE UNIQUE INDEX Stusno ON Student(Sno);
CREATE UNIQUE INDEX Coucno ON Course(Cno);
CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);
ASC表示升序,DESC表示降序。缺省值:ASC。
第一条语句表示在Student表根据学号升序建立索引Stusno。
第二条语句表示在Course表根据课程号升序建立索引Coucno。
第三条语句表示在SC表先根据学号升序排列,(选课表一个学生可能选了多个课程)在学号相同的情况下,课程号降序排列,建立索引SCno。
【例3.14】将SC表的SCno索引名改为SCSno。
ALTER INDEX SCno RENAME TO SCSno;
/*“RENAME”附近有语法错误。*/
这时候就该去官方网站SQL文档查询了,找到正确代码格式应为
EXEC sp_rename N'SC.SCno',N'SCSno',N'INDEX' ;
GO
修改成功
【例3.15】
这个索引之前没建,现在先建好
CREATE UNIQUE INDEX Stusname ON Student(Sno);
删除索引
DROP INDEX Stusname;
/*显示错误,必须为 DROP INDEX 语句指定表名和索引名。*/
根据提示,我感觉正确代码为
DROP INDEX Student.Stusname;
发现索引删除了
INSERT:
【例3.69】
INSERT
INTO Student(Sno,Sname,Ssex,Sdept,Sage)
VALUES('201215128','陈冬','男','IS',18);
插入元组成功。
【例3.70】
INSERT
INTO Student
VALUES('201215126','张成民','男',18,'CS');
添加成功。上一个例子也是插入信息的,这两个相比发现,表名后面写上属性名的时候得按照属性名的顺序对其赋值,需要一一对应。这个例子表名后未给属性名,这时新元组的各属性插入要与建表时各属性添加的顺序一致。
【例3.71】
INSERT
INTO SC(Sno,Cno)
VALUES('201215128','1');
/*报错:INSERT 语句与 FOREIGN KEY 约束"FK__SC__Cno__02084FDA"冲突。该冲突发生于数据库"SCHOOL",表"dbo.Course", column 'Cno'。*/
Cno是外码,被参照表是Course。外码要么为空,要么是被参照表里已有的。我还没在课程表添加课程,所以课程号1是非法的。
现在先在课程表里添加元组。
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES ('1','数据库',NULL,4);
注意的是!Cpno是外码,被参照表是本身,现在Course表里只有1,所以Cpno要么为空,要么为1。处理方法:Cpno这一列可以先让它是空的,等把课程都添加完成之后,再补充这一列,就不会报错了。
这会再执行插入选课记录的语句就可以了。
INSERT
INTO SC(Sno,Cno)
VALUES('201215128','1');
INTO子句指出了两个属性名,此时系统将在新插入记录的Grade列上自动地赋空值。
或者:
INSERT
INTO SC
VALUES('201215128','1',NULL);
因为没有指出SC表的属性名,在Grade列上要明确给出空值。
注意建表时规定SC表的Sno是外码,被参照表是Student;SC表的Cno是外码,被参照表是Course。所以,在SC表添加元组时要注意这两个属性必须是这两个表里已经有的!
错误例子
INSERT
INTO SC(Sno,Cno)
VALUES('201215125','4');
/*报错:INSERT 语句与 FOREIGN KEY 约束"FK__SC__Sno__01142BA1"冲突。该冲突发生于数据库"SCHOOL",表"dbo.Student", column 'Sno'。*/
SELECT:
/*在表里插入元组*/
INSERT INTO Student(Sno,Sname,Ssex,Sdept,Sage) VALUES ('201215121','李勇','男','CS',20);
INSERT INTO Student(Sno,Sname,Ssex,Sdept,Sage) VALUES ('201215122','刘晨','女','CS',19);
INSERT INTO Student(Sno,Sname,Ssex,Sdept,Sage) VALUES ('201215123','王敏','女','MA',18);
INSERT INTO Student(Sno,Sname,Ssex,Sdept,Sage) VALUES ('201215125','张立','男','IS',19);
SELECT * FROM Student /*显示整张表*/
【例3.16】查询全体学生的学号和姓名
SELECT Sno,Sname
FROM Student;
有点不理解的是张成民这个名字在查询表里为什么就显示一个张????(后来发现列是可调节的,把列调宽一点就能显示‘张成民’完整的了)
【例3.17】查询全体学生的姓名、学号、所在系。
SELECT Sname,Sno,Sdept
FROM Student;
【例3.18】查询所有学生的详细记录
SELECT *
FROM Student;
等价于
SELECT Sno,Sname,Ssex,Sdept,Sage
FROM Student;
【例3.19】查询全体学生的姓名及出生年份。
SELECT子句<目标列表达式>不仅可以是表中的属性列,也可以是表达式。
SELECT Sname,2014-Sage
FROM Student;
【例3.20】查询全体学生的姓名、出生年份和所在院系,要求用小写字母表示系名。
SELECT Sname,'Year of Birth:',2014-Sage,LOWER(Sdept)
FROM Student;
可以通过指定别名来改变查询结果的列标题。
SELECT Sname NAME,'Year of Birth:' BIRTH,2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT
FROM Student;
【例3.21】查询选修了课程的学生的学号
先补充一下课程表和选课表。
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES ('2','数学',NULL,4);
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES ('3','信息系统',NULL,4);
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES ('4','操作系统',NULL,4);
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES ('5','数据结构',NULL,4);
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES ('6','数据处理',NULL,4);
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) 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
INSERT INTO SC(Sno,Cno,Grade) VALUES ('201215121','2',85);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('201215121','3',88);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('201215122','2',90);
INSERT INTO SC(Sno,Cno,Grade) VALUES ('201215122','3',80);
SELECT * FROM SC
查询选修了课程的学生的学号
SELECT Sno
FROM SC;
等价于
SELECT ALL Sno
FROM SC;
这时的查询结果会有重复行,想去掉重复行必须指定DISTINCT,如果没有指定DISTINCT关键词,就默认ALL(保留所有行)。
【例3.22】
SELECT Sname
FROM Student
WHERE Sdept='CS';
【例3.23】
SELECT Sname,Sage
FROM Student
WHERE Sage<20;
【例3.24】
SELECT DISTINCT Sno
FROM SC
WHERE Grade<60;
用DISTINCT可以在一个学生多门课程不及格时,他的学号也只列一次。
【例3.25】
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;
在20岁和23岁之间的。
/*等价于*/
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage>=20 AND Sage<=23;
【例3.26】
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;
/*等价于*/
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage<20 OR Sage>23;
【例3.27】
SELECT Sname,Ssex
FROM Student
WHERE Sdept IN('CS','MA','IS');
IN用来查找属性值属于指定集合的元组,CS或MA或IS。
【例3.28】
SELECT Sname,SSex
FROM Student
WHERE Sdept NOT IN('CS','MA','IS');
NOT IN用于查找属性值不属于指定集合的元组。不在CS,不在MA,不在IS。
用时:4个半小时(一天写一两个小时,写了三次的成果)