📖 前言:SQL中常用的数据更新操作也成为数据操作或数据操纵,包括插入数据、删除数据和修改数据三个方面的功能。
视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。视图在数据库中并不是以数值存储集形式存在,除非是索引视图。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。对其中所引用的基础表来说,视图的作用类似于筛选。


可以一次插入多个元组
语句格式:
INSERT
INTO <表名> [(<属性列1>[,<属性列2 >…)]
VALUES (<常量1> [,<常量2>] … )
功能:将新元组插入指定表中
INTO子句
VALUES子句
注意:DBMS在执行插入语句时会检查所插元组是否破坏表上已定义的完整性规则,包括
例1:将一个新学生记录(学号Sno:20211025;姓名Sname:育锐;性别Ssex:男;年龄Sage:20;专业名Smajor:网络工程;籍贯Shometown:广东揭阳)插入Student表中。
INSERT INTO Student (Sno, Smajor, Shometown, Sname, Ssex, Sage)
VALUES ('20211025', '网络工程', '广东揭阳', '育锐', '男',20);
在上例中,属性列表的顺序与表结构中的顺序不一致,因此不能省略INTO子句中的属性列表,但是若此例表示为:
INSERT INTO Student (Sno,Sname,Ssex, Sage,Smajor Shometown, )
VALUES ('20211025', '育锐', '男',10,'网络工程', '广东揭阳');
则该语句可简写为:
INSERT INTO STUDENT
VALUES ('20211025', '育锐', '男',10,'网络工程', '广东揭阳');
例2:插入课程(课程号Cno:‘1000’, 课程名Cname:‘线性代数’, 无先修课程,学分Ccredit:1.5)。
INSERT INTO Course(Cno, Cname, Cpno, Ccredit)
VALUES ('1000', '线性代数', NULL, 1.5);
语句格式:
INSERT
INTO <表名> [(<属性列1>[,<属性列2 >…)]
子查询;
功能:将子查询结果插入指定表中
INTO子句(与插入元组类似)
子查询
例3:在数据库新建一个表,存放STUDENT表中各专业的学生人数。
首先在数据库中新建一张表,存放各专业的名称及学生人数。
CREATE TABLE Major_num
(专业名 char(12),人数 int);
然后求得各专业的人数并插入新建的表中。
INSERT INTO Major_num
SELECT Smajor,count(Sno) /*不能用sum*/
FROM STUDENT
GROUP BY Smajor;
专业名
人数
1
计算机科学与技术
4
2
软件工程
4
3
网络工程
5
专业名 人数 1计算机科学与技术42软件工程43网络工程5
语句格式:
UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>]…
[WHERE <条件>];
功能:修改指定表中满足WHERE子句条件的元组
SET子句
WHERE子句
三种修改方式
注意:DBMS在执行修改语句时会检查所修改元组是否破坏表上已定义的完整性规则,包括
例4:【带子查询的修改】:
将SC表中“计算机科学与技术”专业的所有的学生成绩增加2分。
UPDATE SC /*UPDATE后面只能跟一个表,如果需要修改多个就嵌套*/
SET Grade = Grade +2
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Smajor='计算机科学与技术');
语句格式:
DELETE
FROM <表名>
[WHERE <条件>];
功能:删除指定表中满足WHERE子句条件的元组
WHERE子句
注意:DROP是直接删除整个表
DBMS在执行删除语句时,会检查所删元组是否破坏表上已定义的完整性规则。
三种删除方式
例5:【带子查询的修改】:
在SC表中删除“计算机科学与技术”专业的所有学生的选课信息。
DELETE
FROM SC
WHERE Sno in
( SELECT Sno
FROM Student
WHERE Smajor='计算机科学与技术' )
视图的特点
视图的作用(优点):
基于视图的操作:查询、删除、受限更新、定义基于该视图的新视图
视图的UPDATE、DELETE、INSERT INTO(有受限),数据更新与基本表同步。
❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页
语句格式:
CREATE VIEW
<视图名> [(<列名> [,<列名>]…)]
[WITH ENCRYPTION];
AS <子查询>
[WITH CHECK OPTION];
组成视图的属性列名:全部省略或全部指定
子查询:
ORDER BY子句和DISTINCT(SQL Server中允许)短语With check option:
RDBMS执行CREATE VIEW语句时只是把视图定义存入数据字典,并不执行其中的SELECT语句。
在对视图查询时,按视图的定义从基本表中将数据查出。
常见视图形式:
例6:建立“网络工程”专业的学生选课信息视图NW_VIEW,包括学生的学号、姓名、课程号、成绩,且要保证对该视图进行修改和插入操作时都是“网络工程”专业的学生。
CREATE VIEW NW_VIEW
AS SELECT Student.Sno, Sname, SC.Cno, Grade
FROM Student,SC
WHERE Student.Sno=SC.Sno AND Smajor ='网络工程'
WITH CHECK OPTION ;
对NW_VIEW视图的更新操作:
例7:创建一个视图NW_VIEW_20160303,该视图中定义的是学号为“20160303”学生的选课信息。
分析,该例可以直接对表进行查询建立视图,也可以对视图进行查询建立视图。
CREATE VIEW NW_VIEW_20160303
AS SELECT *
FROM NW_VIEW
WHERE Sno='20160303'
例8:定义学生选修总学分的视图Total_Credit,包括该学生的学号和总学分。
CREATE VIEW Total_Credit (Vno, VCredit)
AS SELECT Sno, SUM(Course.Ccredit)
FROM SC, Course
WHERE SC.Cno=Course.Cno
GROUP BY Sno
Vno
VCredit
1
20160101
9.5
2
20160102
3.5
3
20160201
3.5
4
20160203
4
5
20160204
3.5
6
20160303
27
Vno VCredit 1201601019.52201601023.53201602013.542016020345201602043.562016030327
/*写法2*/
CREATE VIEW Total_Credit
AS SELECT Sno, SUM(Course.Ccredit) AS VCredit
FROM SC, Course
WHERE SC.Cno=Course.Cno
GROUP BY Sno
例9:查询“计算机科学与技术”和“软件工程”两个专业的所有学生的学号、姓名、专业、总学分。
SELECT Vno, Sname, Smajor, Vcredit
FROM Student, Total_Credit
WHERE Smajor IN ('计算机科学与技术','软件工程') and Sno=Vno
Vno
Sname
Smajor
Vcredit
1
20160101
徐成波
计算机科学与技术
9.5
2
20160102
黄晓君
计算机科学与技术
3.5
3
20160201
黄晓君
软件工程
3.5
4
20160203
张顺峰
软件工程
4
5
20160204
洪铭勇
软件工程
3.5
Vno Sname Smajor Vcredit 120160101 徐成波 计算机科学与技术 9.5220160102 黄晓君 计算机科学与技术 3.5320160201 黄晓君 软件工程 3.5420160203 张顺峰 软件工程 4520160204 洪铭勇 软件工程 3.5
DBMS在执行此查询时,首先进行有效性检查,然后从数据字典中取出Total_Credit视图的定义,再与Student基本表的连接查询进行合并消解,转换为对基本表Student、Course和SC的查询。
更新视图操作包括:
在DB2中对视图的更新有如下限制:
(1)若视图的属性来自属性表达式或常数,则不允许对视图执行INSERT和UPDATE操作,但允许执行DELETE操作。
(2)若视图的属性来自聚集函数,则不允许对此视图更新。
(3)若视图定义中有GROUP BY子句,则不允许对此视图更新。
(4)若视图定义中有DISTINCT任选项,则不允许对此视图更新。
(5)若视图定义中有嵌套查询,并且嵌套查询的FROM子句涉及导出该视图的基本表,则不允许对此视图更新。
(6)如果在一个不允许更新的视图上再定义一个视图,这种二次视图是不允许更新的。
PS:书上的这条,请注意:
若视图由两个以上的基本表导出,则不允许对此视图更新。-----实际上是可以的。
小结:只有行列子集视图允许更新,但我们一般不对视图做更新。
例10:将视图NW_VIEW中学号“20160303”和课程号“1006”的成绩修改为91。
UPDATE NW_VIEW
SET Grade=91
WHERE Sno='20160303' AND Cno='1006'
本例中该更新语句是可以执行的,且执行时也是转换为对基本表的更新。但是其他几个视图的更新是不允许的。
视图修改的SQL语句格式为:
ALTER VIEW < 视图名>
[WITH ENCRYPTION];
AS <子查询>
[WITH CHECK OPTION];
如果原来的视图定义中使用了WITH ENCRYPTION或WITH CHECK OPTION选项,则只有在ALTER VIEW中也包含这些选项时,这些选项才能有效。修改视图并不会影响相关对象,除非对视图定义的更改使得该相关对象不再有效。
语句的格式:
DROP VIEW <视图名>;
该语句从数据字典中删除指定的视图定义
DROP VIEW语句删除子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这时子查询生成的临时派生表(Derived Table)成为主查询的查询对象
例11:找出每个学生超过他自己选修课程平均成绩的课程号。
有哪些解决方案?
方法一:
SELECT Sno,Cno,grade as '这门课的成绩',avg_grade
FROM SC, (SELECT Sno, Avg(Grade) FROM SC
GROUP BY Sno) AS Avg_sc(avg_sno,avg_grade) /*定义了一个临时表*/
WHERE SC.Sno = Avg_sc.avg_sno and
SC.Grade >=Avg_sc.avg_grade
方法二:
CREATE VIEW V_avg_sc (avg_sno,avg_grade)
AS SELECT Sno, Avg(Grade) FROM SC GROUP BY Sno;
SELECT Sno, Cno,grade as '这门课的成绩', avg_grade
FROM SC,V_avg_sc
where Sno = avg_sno and Grade >=avg_grade;
Sno
Cno
这门课的成绩
avg_grade
1
20160101
1006
91
90
2
20160101
1008
92
90
3
20160102
1005
82
82
4
20160201
1005
90
90
5
20160203
1003
89
89
6
20160204
1005
96
96
7
20160303
1001
88
85
8
20160303
1002
86
85
9
20160303
1004
98
85
10
20160303
1006
91
85
Sno Cno 这门课的成绩 avg\_grade 120160101100691902201601011008929032016010210058282420160201100590905201602031003898962016020410059696720160303100188858201603031002868592016030310049885102016030310069185
派生表是一种从查询表达式派生出虚拟结果表的表达式。
派生表与其他表一样出现在查询的FROM子句中。派生表仅存在于外部查询中.
使用派生表的一般形式如下:
FROM (SELECT * FROM TA WHERE ...) AS T
派生出来的表必须是一个有效的表,因此,它必须遵守以下几条规则:
ORDER BY(除非指定了TOP)如果子查询中没有聚集函数,派生表可以不指定属性列,子查询SELECT子句后面的列名为其缺省属性。
例12:查询所有选修了1号课程的学生姓名,可以用如下查询完成:
SELECT Sname
FROM Student,
(SELECT Sno FROM SC WHERE Cno=' 1 ') AS SC1
WHERE Student.Sno=SC1.Sno;
SELECT Sname
FROM Student, SC
WHERE Student.Sno=SC.Sno and Cno=' 1 ';
SELECT Sname
FROM Student
WHERE sno in
(select sno from sc where cno='1')
SELECT Sname
FROM Student
WHERE exists
(select * from sc where sno=student.sno and cno='1')
CREATE VIEW v_cno_1
AS SELECT * FROM student,sc
WHERE sc.sno=student.sno and cno='1';
SELECT sname FROM v_cno_1;
【单选题】职工表EMP和部门表DEPT如图所示,其中有下划线的属性为主键,有波浪线的属性为外键。下面操作不能正确执行的是( )。
EMP
职工号
‾
部门号
∼
∼
∼
∼
∼
职工名
E
01
D
03
李路
E
25
D
01
武明
E
19
D
04
崔浩
E
32
D
01
李颖
职工号 _部门号∼∼∼∼∼ 职工名 E01D03李路E25D01武明E19D04崔浩E32D01李颖
DEPT
部门号
‾
部门名
D
01
研发部
D
02
市场部
D
03
人事部
D
04
财务部
部门号 _ 部门名 D01研发部D02市场部D03人事部D04财务部
A.检索部门号为“D05”的职工号
B.将EMP表中职工“李路”的部门号改为空值
C.删除职工“崔浩”的记录
D.在EMP表中插入记录(“E18”,“D05”,“育锐”)
【多选题】对于student-course数据库,如果要查询没有选修了1号课程的学生姓名,以下选项正确是( )
A.SELECT Sname FROM Student, SC
WHERE Student.Sno=SC.Sno and Cno<>’ 1 ‘;
B.SELECT Sname FROM Student
WHERE sno not in (select sno from sc where cno=‘1’)
C.SELECT Sname FROM Student, (SELECT Sno FROM SC WHERE Cno<>’ 1 ') AS SC1
WHERE Student.Sno=SC1.Sno;
D.SELECT Sname FROM Student
WHERE not exists
(select * from sc where sno=student.sno and cno=‘1’)
E.create view v_cno_1
as select * from student,sc where sc.sno=student.sno and cno<>‘1’;
select sname from v_cno_1;
F.SELECT Sname FROM Student
WHERE sno in (select sno from sc where cno<>‘1’)
G.SELECT Sname FROM Student
WHERE not exists
(select * from sc where sno=student.sno and cno<>‘1’)
【单选题】若用如下的SQL语句创建一个Student表:
CREATE TABLE student (NO char(4) not null,
NAME Char(8) not null,
SEX char(2),
AGE numeric(2))
可以插入到student表中的是
A、(‘1031’,’育锐’,男,23)
B、(‘1031’,’育锐’,NULL,NULL)
C、(NULL,’育锐’,’男’,’23’)
D、(’1031’,NULL,’男’,23)
【单选题】在视图上不能完成的操作是( )
A、在视图上定义新的视图
B、查询操作
C、更新视图
D、在视图上定义新的基本表
【单选题】当修改基表数据时,视图________。
A、需要重建
B、可以看到修改结果
C、无法看到修改结果
D、不允许修改带视图的基表
【填空题】
设有如下关系表R:
R(NO,NAME,SEX,AGE,CLASS)
其中NO为学号,NAME为姓名,SEX为性别,AGE为年龄,CLASS为班号。写出实现下列功能的SQL语句。
①插入一个记录(25,‘李明’,‘男’,21,‘95031’);
②插入‘95031’ 班学号为30、姓名为‘郑和’的学生记录;
③将学号为 10的学生姓名改为 ‘王华’;
④将所有‘95101’ 班号改为‘95091’;
⑤删除学号为20的学生记录;
⑥删除姓‘王’的学生记录;
用SQL语句建立关系代数课后习题第19题中的四个表🔎 关系代数学习笔记
S(SNO,SNAME,STATUS,SCITY);
P(PNO,PNAME,COLOR,WEIGHT);
J(JNO,JNANE,JCITY);
SPJ(SNO,PNO,JNO,QTY)。
其中在SPJ表中,SNO、PNO和JNO是外键分别参照S、P、J中的相应字段。
注意:只需要创建SPJ表即可,但要记得外键和主键
针对上题中四个表,用SQL语句完成下述操作。
(1)找出使用供应商S1所供零件的工程号码。
(2)找出工程项目J2使用的各种零件名称及其数量。
(3)找出上海厂商供应的所有零件号码。
(4)找出使用上海产的零件的工程名称。
(5)找出没有使用天津产零件的工程号码。
(6)将由供应商S5供给工程代码为J4的零件P6改为由S3供应。
(7)从供应商关系中删除S2的记录,并从供应零件关系中删除相应的记录。
(8)请将(S2,J6,P4,500)插入供应情况表。
对于教学数据库的三个基本表:
S(SNO ,SNAME ,AGE ,SEX)
SC(SNO ,CNO ,GRADE)
C(CNO ,CNAME ,TEACHER)
试用SQL语句表达下列查询:
(1)查询姓刘的老师所授课程的课程号和课程名。
(2)查询年龄大于23岁的男同学的学号和姓名。
(3)查询学号为S3学生所学课程的课程号、课程名和任课教师名。
(4)查询“张小飞”没有选修的课程号和课程名。
(5)查询至少选修了3门课程的学生的学号和姓名。
(6)在SC中删除尚无成绩的选课元组。
(7)把“高等数学”课的所有不及格成绩都改为60。
(8)把低于所有人总平均成绩的女同学的成绩提高5%。
(9)向C中插入元组(‘C8’,‘VC++’,‘王昆’)。
请为三建工程项目建立一个供应情况的视图,包括供应商代码(SNO)、零件代码(PNO)、供应数量(QTY),并完成以下查询。
(1)找出三建工程项目使用的各种零件代码及其数量。
(2)找出供应商S1的供应情况。
答案:1.D(解析:因为EMP表的部门号是外键,参照的是DEPT表的主键,而DEPT表里没有D05,因此无法正确执行) 2.BD(解析:ACEFG都是否定在内层,不行) 3.B 4.D 5.B
6.第一空: INSERT INFO R VALUES(25, ‘李明’, ‘男’,21, ‘95031’);
第二空: INSERT INFO R(NO, NAME, CLASS) VALUES (30, ‘郑和’, ‘95031’);
第三空: UPDATE R
SET NAME=‘王华’
WHERE NO=‘10’
第四空: UPDATE R
SET CLASS = ‘95091’
WHERE CLASS=‘95101’
第五空: DELETE FROM R
WHERE NO = ‘20’
第六空: DELETE FROM R
WHERE NAME LIKE’王%’
CREATE TABLE SPJ
( SNO VARCHAR(2)REFERENCES S(SNO),
PNO VARCHAR(2),
JNO VARCHAR(2),
QTY NUMERIC(4),
PRIMARY KEY (SNO,PNO,JNO),
FOREIGN KEY(PNO) REFERENCES P(PNO),
FOREIGN KEY(JNO) REFERENCES J(JNO)
);
/* 注意:本题中主键约束只能放在表级,外键约束既可以放在表级也可以放在行级。 */
/*(1)*/
SELECT DISTINCT JNO FROM SPJ WHERE SNO=’S1’
/*(2)*/
SELECT PNAME,QTY FROM P,SPJ
WHERE P.PNO=SPJ.PNO AND JNO=’J2’
/*(3)*/
SELECT DISTINCT PNO FROM SPJ
WHERE SNO IN
(SELECT SNO FROM S WHERE SCITY=’上海’)
/*(4)*/
SELECT JNAME FROM J,SPJ,S
WHERE J.JNO=SPJ.JNO AND SPJ.SNO=S.SNO AND S.SCITY=’上海’
--或者
SELECT JNAME FROM J
WHERE JNO IN
(SELECT JNO FROM SPJ,S
WHERE SPJ.SNO=S.SNO AND S.SCITY=’上海’)
--或者
SELECT JNAME FROM J WHERE JNO IN
(SELECT JNO FROM SPJ WHERE SNO IN
(SELECT SNO FROM S WHERE SCITY=’上海’))
/*(5)*/
SELECT JNO FROM J WHERE NOT EXISTS
(SELECT * FROM SPJ WHERE JNO= J.JNO AND SNO IN
(SELECT SNO FROM S WHERE SCITY=’天津’))
--或者
SELECT JNO FROM J WHERE JNO NOT IN
(SELECT JNO FROM SPJ WHERE SNO IN
(SELECT SNO FROM S WHERE SCITY=’天津’))
--或者
SELECT JNO FROM J WHERE JNO NOT IN
(SELECT JNO FROM SPJ,S
WHERE SPJ.SNO=S.SNO AND SCITY=’天津’)
--或者
(SELECT JNO FROM J)
EXCEPT
(SELECT JNO FROM SPJ,S
WHERE SPJ.SNO=S.SNO AND SCITY=’天津’)
/*(6)*/
UPDATE SPJ SET SNO=’S3’
WHERE SNO=’S5’ AND PNO=’P6’ AND JNO=’J4’
/*(7)*/
DELETE FROM SPJ WHERE SNO=’S2’;
DELETE FROM S WHERE SNO=’S2’;
/* 本题一定要注意执行的顺序。
Delete from SPJ,S where 是错误的!!!
Update语句后面什么时候都不可能出现两个表
需要用嵌套查询 */
/*(8)*/
INSERT INTO SPJ(SNO,JNO,PNO,QTY)
VALUES (‘S2’,‘J6’,’P4’,500)
--或者
INSERT INTO SPJ
VALUES (‘S2’,’P4’,’J6’,500)
/*(1)*/
SELECT CNO,CNAME FROM C
WHERE TEACHER LIKE ’刘%’;
/*(2)*/
SELECT SNO ,SNAME FROM S
WHERE AGE>23 AND SEX=’男’;
/*(3)*/
SELECT * FROM C WHERE CNO IN
(SELECT CNO FROM SC WHERE SNO=’S3’);
/*(4)*/
SELECT CNO,CNAME FROM C WHERE NOT EXISTS
(SELECT * FROM SC WHERE CNO=C.CNO AND SNO IN
(SELECT SNO FROM S WHERE SNAME=’张小飞’));
/*本题可以用EXCEPT*/
/*(5)*/
SELECT SNO,SNAME FROM S WHERE SNO IN
(SELECT SNO FROM SC GROUP BY SNO HAVING COUNT(*)>=3)
COUNT(CNO)也可以
--或者
SELECT SNO,SNAME FROM S
WHERE (SELECT COUNT(CNO) FROM SC WHERE SNO=S.SNO)>=3
/*上面这个思路是:对于S表中的每一个学生,去检查他选修的课程门数是否大于等于3*/
--或者用连接查询,但一般不用,没有必要
SELECT SNO,SNAME FROM S WHERE SNO IN
( SELECT S.SNO FROM S,SC WHERE S.SNO=SC.SNO
GROUP BY S.SNO HAVING COUNT(*)>=3)
/*(6)*/
DELETE FROM SC WHERE GRADE IS NULL;
/*(7)*/
UPDATE SC SET GRADE=60
WHERE GRADE<60 AND CNO IN
(SELECT CNO FROM C WHERE CNAME=’高等数学’)
/*(8)*/
UPDATE SC
SET GRADE=GRADE+GRADE*0.05
WHERE SNO IN (SELECT SNO FROM S WHERE S.SEX=’女’)
AND GRADE < (SELECT AVG(GRADE) FROM SC)
/*(9)*/
INSERT INTO C VLAUES(‘C8’,‘VC++’,‘王昆’)
--或者
INSERT INTO C (CNO ,CNAME ,TEACHAR)
VLAUES(‘C8’,‘VC++’,‘王昆’)
CREATE VIEW V_SPJ
AS
SELECT DISTINCT SNO,PNO,QTY FROM SPJ
WHERE JNO in
(SELECT JNO FROM J WHERE JNAME=’三建’)
--或者
CREATE VIEW V_SPJ
AS
SELECT DISTINCT SNO,PNO,QTY FROM SPJ,J
WHERE SPJ.JNO=J.JNO AND JNAME=’三建’
/*(1)*/
SELECT PNO,SUM(QTY) FROM V_SPJ
Group by pno
/*(2)*/
SELECT * FROM V_SPJ
WHERE SNO=’S1’
OK,以上就是本期知识点“基本表更新(INSERT、UPDATE、ALTER、DELETE)与视图VIEW”的知识啦~~ ,感谢友友们的阅读。后续还会继续更新,欢迎持续关注哟📌~
💫如果有错误❌,欢迎批评指正呀👀~让我们一起相互进步🚀
🎉如果觉得收获满满,可以点点赞👍支持一下哟~
❗ 转载请注明出处
作者:HinsCoder
博客链接:🔎 作者博客主页