第三章完整版->有道云笔记
3.数据更新
- 插入数据
插入元组
I. 指出表名和属性名,属性的顺序可与CREATE TABLE的顺序不同。
/* 将一个新学生元组插入到Student表中 */
INSERT
INTO Student(Sno, Sname, Ssex, Sdept, Sage)
VALUES('201215128', '陈学冬', '男', 'CS', 20);
II. 指出表名,不指出属性名,新元组要在表的所有属性列上都指定值,并与CREATE TABLE次序一一对应。
/* 插入一条选课记录('201215128','1'),没有指出SC属性名时,在Grade列上要明确给出空值 */
INSERT
INTO SC
VALUES('201215128', '1', NULL);
插入子查询结果
/* 语法格式 */
INSERT
INTO <表名>([<属性列1>[<,属性列2>]...])
子查询;
/* 对Student表按系分组求平均年龄,再将系名和对应的学生平均年龄存入新表 */
INSERT
INTO Dept_age(Sdept, Avg_age) /* Dept_age存放系名和对应的学生平均年龄 */
SELECT Sdept, AVG(Sage)
FROM Student
GROUP BY Sdept;
- 修改数据
一般格式
UPDATE <表名>
SET <列名>=<表达式> [,<列名>=<表达式>] ...
[WHERE <条件>];
修改某一个元组的值
/* 将学生201215121的年龄改为22岁 */
UPDATE Student
SET Sage = 22
WHERE Sno = '201215121';
修改多个元组的值
/* 将所有学生的年龄增加1岁 */
UPDATE Student
SET Sage = Sage + 1;
带子查询的修改语句
/* 将计科系全体学生成绩置零 */
UPDATE SC
SET Grade = 0
WHERE Sno IN
(SLECT Sno
FROM Student
WHERE Sdept = 'CS');
- 删除数据
一般格式
DELETE
FROM <表名>
[WHERE <条件>];
删除某一个元组的值
/* 删除学号为201215128的学生记录 */
DELETE
FROM Student
WHERE Sno = '201215128';
删除多个元组的值
/* 删除所有的学生选课记录 */
DELETE
FROM SC;
[注]:DELETE删除的是表中数据,而不是关于表的定义。DROP才可删除表。
带子查询的删除语句
/* 删除计科系所有学生的选课记录 */
DELETE
FROM SC
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept = 'CS');
4.空值的处理
- 空值的产生
INSERT INTO SC(Sno, Cno, Grade)
VALUES('201216127', '1', NULL); /* 在插入时该学生还没有考试成绩,取空值 */
- 空值的判断
判断一个属性的值是否为空值,用IS NULL或IS NOT NULL来表示。
/* 从Student表中找出漏填了数据的学生信息 */
SELECT *
FROM Student
WHRER Sname IS NULL OR Ssex IS NULL OR Sage IS NULL OR Sdept IS NULL;
- 空值的约束条件
属性(或者域)定义中有NOT NULL约束条件的 / 加了UNIQUE限制的属性 / 码属性不能取空值。
- 空值的算术运算、比较运算和逻辑运算
空值与另一个值(包括另一个空值)的算术运算的结果为空值,空值与另一个值(包括另一个空值)的比较运算结果为UNKNOWN。传统二值逻辑拓展成了三值逻辑。
/* 选出选修1号课程不及格的学生以及缺考的学生 */
SELECT Sno
FROM SC
WHERE Cno = '1' AND (Grade < 60 OR Grade IS NULL);
5.视图
视图是从一个或几个基本表(或视图)导出的表,是一个虚表。数据库中只存放视图的定义,而不存放视图对应的数据。视图就像一个窗口,透过它可以看到数据库中自己感兴趣的数据及其变化。
-
定义视图
I. 建立视图
/* 一般格式 */ CREATE VIEW <视图名>[(<列名>[,<列名>]...)] AS <子查询> /* 子查询可以是任意的SELECT语句 */ [WITH CHECK OPTION]; /* 对视图进行UPDATE、INSERT、DELETE时要保证满足视图定义中的谓词条件(即子查询中的条件表达式) */ /* 建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生 */ CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept = 'IS' WITH CHECK OPTION; /* 检查是不是还在信息系里 */
[注]:由于在定义IS_Student视图时,加上了WITH CHECK OPTION子句,以后对该视图进行插入、修改和删除操作时,关系数据库管理系统会自动加上Sdept='IS'的条件。
/* 建立信息系选修了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';
[注]:由于视图IS_S1的属性列中包含了Student表和SC表同名列Sno,所以必须在视图名后说明视图的各个属性名。
/* 建立信息系选修了1号课程且成绩在90分以上的学生的视图 */ CREATE VIEW IS_S2 AS SELECT Sno, Sname, Grade FROM IS_S1 WHERE Grade >= 90;
[注]:视图可以建立在一个或多个已定义好的视图上,或建立在基本表与视图之上。这里的视图IS_S2就是建立在视图IS_S1之上的。
/* 定义一个反映学生出生年份的视图 */ CREATE VIEW BT_S(Sno, Sname, Sbirth) AS SELECT Sno, Sname, 2014-Sage FROM Student;
[注]:由基本数据经各种计算派生出的数据一般是不存储的,这些派生属性由于在基本表中并不实际存在,称为虚拟列。带虚拟列的视图也称带表达式的视图。
/* 将学生的学号及平均成绩定义为一个视图 */ /* 列平均成绩是通过聚集函数得到的,所以S_G视图必须指明各属性列名*/ CREATE VIEW S_G(Sno, Gavg) AS SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno;
[注]:用带有聚集函数和GROUP BY子句的查询来定义视图,这种视图称为分组视图。
/* 将Student表中所有女生记录定义为一个视图 */ CREATE VIEW F_Student(F_sno, name, sex, age, dept) AS SELECT * FROM Student WHERE Ssex = '女';
[注]:F_Student视图的属性列与Student表的属性列一一对应。如果修改了基本表Student的结构,与视图的映像关系就会被破坏,该视图就不能正常工作了。因此,最好在修改基本表之后删除由该基本表导出的视图,然后重建这个视图。
II. 删除视图
/* 级联删除 */ DROP VIEW <视图名> [CASCADE];
DROP VIEW BT_S; /* 成功执行 */ DROP VIEW IS_S1; /* 拒绝执行,由于IS_S1视图上还导出了IS_S2 */ DROP VIEW IS_S1 CASCADE; /* 删除了IS_S1和由它导出的所有视图 */
查询视图
/* 在信息系学生的视图中找出年龄小于20岁的学生 */
SELECT Sno, Sage
FROM IS_Student
WHERE Sage < 20;
/* 转换后的查询语句为 */
SELECT Sno, Sage
FROM Student
WHERE Sdept = 'IS' AND Sage < 20;
/* 涉及视图与基本表的连接:查询选修了1号课程的信息系学生 */
SELECT IS_Student.Sno, Sname
FROM IS_Student, SC
WHERE IS_Student.Sno = SC.Sno AND SC.Cno = '1';
[注]:目前多数关系数据库系统对行列子集视图的查询均能进行正确转换,但对非行列子集视图的查询就不一定能做转换了。如P125 例3.94。
- 更新视图
更新视图是指通过视图来插入、删除和修改数据。由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新。
/* 为信息系学生视图IS_Student中某学生修改姓名 */
UPDATE IS_Student
SET Sname = '刘辰'
WHERE Sno = '201215122';
/* 转换后的更新语句为 */
UPDATE Student
SET Sname = '刘辰'
WHERE Sno = '201215122' AND Sdept = 'IS';
/* 向信息系学生视图IS_Student中插入一个新的学生记录 */
INSERT
INTO IS_Student
VALUES('201215129','赵信',20);
/* 转换后的插入语句为 */
INSERT
INTO Student(Sno, Sname, Sage, Sdept)
VALUES('201215129','赵信',20,'IS'); /* 系统自动将系名'IS'放入VALUES子句中 */
[注]:在关系数据库中,并不是所有视图都可更新。一般地,行列子集视图是可更新的。
例如,如果想将视图S_G中学号为'201215128'的学生的平均成绩改为90分,SQL语句如下:
UPDATE
SET Gavg = 90
WHERE Sno = '201215128';
对这个视图的更新无法转换为对基本表SC的更新的。因为系统无法修改各科成绩,以使平均成绩为90。所以S_G视图是不可更新的。
- 视图的作用
视图能够简化用户的操作:
用户所做的只是对一张虚表的查询,而虚表如何而来,用户无需了解。
视图使用户能以多种角度看待同一数据。
视图对重构数据库提供了一定程度的逻辑独立性:数据的逻辑独立性指的是当数据库重构造时,如增加新的关系或原有关系增加新字段,用户的应用程序不会受影响。
视图能够对机密数据提供安全保护:对不同用户定义不同视图,如在Student表上定义n个视图,每个视图只包含一个院系的学生数据,并只允许每个院系的主任查询和修改本院系学生视图。
适当利用视图可以更清晰地表达查询:如对每个同学找出他获得最高成绩的课程号,可以先定义一个视图,求出每个同学获得的最高成绩,再进行查询。