今天在数据库的课上学习了SQL语句INDEX,INSERT和SELECT,通过例子的练习来加深对他们的理解。
一、INDEX练习
例题:
【3.13】
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表中建立一个索引(按照Sno学号升序),未说明为升序;
第二行语句是指在Course表中建立一个索引(按照Cno课程号升序);
第三行语句是指在SC上建立索引,这里可以注意到后面的列名括号里是有两列的,那这是什么意思呢,学号升序,课程号降序怎么同时排列呢?其实这里的意思是先将表按照第一个,也就是学号Sno升序ASC排列,然后将在第一个上的取值相同的那些记录,再按照第二个,也就是课程号降序的方式进行排列。(学号没有相同的吧(°ー°〃));
【3.14】
(书中语句:)
ALTER INDEX SCno RENAME TO SCSno;
--“RENAME”附近有语法错误。
这个例子我没有运行成功。我查了一下资料,有显示,这个时候使用:
EXEC sp_rename @objname = ‘student.stusno1’, @newname = ‘stusno2’, @objtype = ‘index’
或者
EXEC sp_rename ‘表名.旧索引名’, ‘新索引名’, ‘index’
EXEC sp_rename 'SC.SCno', 'SCSno', 'index'
--注意: 更改对象名的任一部分都可能会破坏脚本和存储过程。
运用这个方法,能够看到左边SC表中的索引名确实变成了SCSno。
【3.15】
(书中语句:)
DROP INDEX Stusno;
--必须为 DROP INDEX 语句指定表名和索引名。
可以看到,再SQL server中,无法正确运行,查阅了资料后,得知正确的方法是:
DROP INDEX Stusno on Student;
这样就ok了。
二、INSERT练习
【3.69】
INSERT
INTO Student (Sno,Sname,Ssex,Sdept,Sage)
VALUES ('201215128','王辉','男','IS',18);
--违反了 PRIMARY KEY 约束“PK__Student__CA1FE464BE1DBD40”。不能在对象“dbo.Student”中插入重复键。重复键值为 (201215128)。
这里应该是插入了一个重复学号。回头看学生表里,确实学号重复了,再换了一个学号后,就可以正常运行了。
【3.70】
INSERT
INTO Student
VALUES ('201215126','张老三','男',18,'CS');
含义是在学生组中插入一个元组。可以看到,into后面的表后没有写属性名,这也是可以的,但这样的话在VALUES中就必须给出所有属性的值。
【小例子】
错误:
INSERT
INTO Course(Cno,Cname,Cpno,Credit)
VALUES ('1','数据库','5',4);
--INSERT 语句与 FOREIGN KEY SAME TABLE 约束"FK__Course__Cpno__2882FE7D"冲突。该冲突发生于数据库"master",表"dbo.Course", column 'Cno'。
正确:
INSERT
INTO Course(Cno,Cname,Cpno,Credit)
VALUES ('1','数据库',NULL,4);
建立Course表的时候,设定Cpno为外键,引用了主键Cno。根据参照完整性规则,外键要么为空,要么源自于其引用的主码。当创建第一个元组时,显然Cno的值是1,所以要么Cpno为空,要么Cpno的值也为1.
【小问题】
给SC添加一行数据(添加的学号和姓名,必须是刚才两张表里面已经有的学号和姓名,why?)
因为建立SC的时候,是吧Student和Course作为参照表来建立的,它的属性Sno和Cno是两个表的主键,是SC的外键,参照完整性规则,外键要么为空,要么是源自于被参照表的主键。
【3.71】
INSERT
INTO SC(Sno,Cno)
VALUES ('201215128 ','1');
也可写成
INSERT
INTO SC
VALUES (' 201215128 ',' 1 ',NULL);
三、SELECT练习
【3.16】
SELECT Sno,Sname
FROM Student;
在所有学生中查询Sno,Sname两列。这种方式可以筛选到表中的若干列。
【3.17】
SELECT Sname,Sno,Sdept
FROM Student;
在所有学生中查询姓名学号,所在系。
【3.18】
SELECT Sno,Sname,Ssex,Sage,Sdept
FROM Student;
等价于
SELECT *
FROM Student;
这是查询全体学生的所有信息。
【3.19】
SELECT Sname,2016-Sage /*假设当时为2016年*/
FROM Student;
SELECT子句后面的不仅可以为表中的属性列,也可以是表达式。
【3.20】
SELECT Sname,'Year of Birth: ',2014-Sage,LOWER(Sdept)
FROM Student;
【3.21】
SELECT Sno FROM SC;
等价于:
SELECT ALL Sno FROM SC;
如果没有指定DISTINCT,缺省为ALL ,此时保留所有的元组。如果有DISTINCT,则消除重复的行。
【3.22】
SELECT Sname
FROM Student
WHERE Sdept='CS';
在Student表中查询系别是‘CS’的学生姓名。WHERE后面跟指定条件。
【3.23】
SELECT Sname,Sage
FROM Student
WHERE Sage < 20;
如图可以看到,查询到的都是Sage<20的学生。
【3.24】
SELECT DISTINCT Sno
FROM SC
WHERE Grade<60;
【3.25】
SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;
BETWEEN a AND b:在a和b之间。
【3.26】
SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;
NOT BETWEEN a AND b:不在a和b之间。
【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 ('IS','MA','CS');
NOT IN <值表> ,表示属性不在值表之内的元组。系别不在‘CS’,‘MA’,'IS’中的。
通过对这几个例子的练习,我能感觉到我对这几个语句明显熟悉了很多,理解也加深了。
第五次作业-用时差不多120分钟。