INSERT / UPDATE / DELETE / NULL / VIEW

数据更新

CRUD —— 增删改查(Create、Retrieve、Update、Delete)

CREATE / ALTER / DROP——对于数据库,表的操作
INSERT / UPDATE / DELETE —— 对数据的操作

1.插入数据——INSERT

包括:

  • 插入元组
INSERT INTO <表名>[(<属性列1>[,<属性列2>...])]
VALUES (<常量1>[,<常量2>...])

INTO后面加表名,属性列名可以与表中属性列排列顺序不一致,如【例3.69】,但VALUES后跟的值必须与所给属性列相对应,也可以省去,如【例3.70】,但省去后,VALUES后面跟的元组值必须与表中顺序完全一致

【例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('200215128','1');
--或者
INSERT INTO SC
VALUES('200215128','1',NULL);
  • 插入子查询结果

语句格式:

INSERT INTO <表名>[(<属性列1>[,<属性列2>...])]
子查询;

子查询SELECT子句的目标列必须与INTO子句匹配,包括个数和类型。

【例3.72】对每一个系,求学生的平均年龄,并把结果存进数据库
每一个系 —— GROUP BY子句
平均年龄 —— 聚集函数
要存进数据库——存进基本表——建表

(一)建表

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;
--属性列也可以省略掉

在这里插入图片描述
RDBMS在插入数据和修改数据时都会自动检查是不是符合完整性规则:实体完整性、参照完整性、用户自定义的完整性。

例:
1.违背实体完整性
在这里插入图片描述
2.违背参照完整性
在这里插入图片描述

2.修改数据——UPDATE

语句:

UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>...]
[WHERE<条件>]

修改满足WHERE子句条件的元组,如果WHERE子句省略,则修改所有元组。
SET子句中的<表达式>用于取代相应属性列的值。

  • 修改某一个元组的值

【例3.73】将学生201215121的年龄改为22岁。

UPDATE Student
SET Sage = 22
WHERE Sno='201215121';

更改前,为20岁
在这里插入图片描述更改后
在这里插入图片描述

  • 修改多个元组的值

【例3.74】将所有学生的年龄增加1岁

UPDATE Student
SET Sage = Sage + 1;

在这里插入图片描述
在这里插入图片描述

  • 带子查询的修改语句

【例3.75】将计算机科学系全体学生的成绩置零

UPDATE SC,Student
SET Grade = 0
WHERE SC.Sno = Student.Sno
   AND Sdept = 'CS';
--上面的是自己写的,完全忘记了是带子查询的示例
--是错误的!!!UPDATE后只能跟一个表名

UPDATE SC
SET Grade = 0
WHERE Sno IN
       (SELECT Sno
       FROM Student
       WHERE Sdept = 'CS');

我在自己写的时候,写成了第一种。这一种是错误的,因为UPDATE后面只能加一个表名,错当成了类似SELECT语句的使用。但是如果删掉Student表,下面的就会报错,所以只能用子查询块实现了。

在这里插入图片描述
其中原 201215003 处的成绩为NULL,现也改为零。

主码可以被修改,但是不能改成重复的。另外就是完整性的限制。
【例】
在这里插入图片描述这里修改 Student的主码,不过错误提示的好像是,因为SC表引用着不能修改。

然后换了,没有SC表引用的两个人,发现主码是可以修改的,只是不能改为重复的。这一点,与PPT上有些不一样。(其中他们两个原来的学号为007和008)
在这里插入图片描述

3.删除数据——DELETE

语句:

DELETE
FROM <表名>
[WHERE <条件>]

删除表中满足WHERE子句条件的元组。若WHERE子句省去后,则表示删除所有元组。删除所有元组后,表的定义还在,即还有这张表,但是表中的数据都没了。
注意删除数据是 DELETE 删除表是 DROP
删除整张表,用的是DROP TABLE <表名>。

  • 删除某一元组的值

【例3.76】删除学号为201215128的学生记录。

DELETE
FROM Student
WHERE Sno='201215128';

在这里插入图片描述
在这里插入图片描述

  • 删除多元组的值

【例3.77】删除所有学生的选课记录

DELETE
FROM SC;

SC中所有数据都没了,但是SC表还在。

  • 带子查询的删除语句

【例3.78】删除计算机科学系所有学生的选课记录

DELETE
FROM SC
WHERE Sno IN
      (SELECT Sno
      FROM Student
      WHERE Sdept='CS');

和修改的情况类似,嵌套子查询。

空值 NULL

空值 —— “不确定”,“不存在”,“无意义”的值

1.空值的产生

【例3.79】向SC表中插入一个元组,学号为“201215126”,课程号为‘1’,成绩为空。

INSERT INTO SC(Sno,Cno,Grade)
VALUES('201215126','1',NULL);
--或
INSERT INTO SC(Sno,Cno)
VALUES('201215126','1');
--没赋值的属性为空值

【例3.80】将Student表中的‘201215200’的学生所属系别改为空值。

UPDATE Studnet
SET Sdept=NULL
WHERE Sno='201215200';

原表中没有这个数据,先做插入。
在这里插入图片描述

2.空值的判断 IS NULL/IS NOT NULL

【例3.81】从Student表中找出漏填了数据的学生信息

SELECT *
FROM Student
WHERE Sname IS NULL OR Ssex IS NULL 
      OR Sdept IS NULL OR Sage IS NULL;

注意是IS NULL,不可以用=。

3.空值的约束

  • 属性定义时有NOT NULL约束的不能为空
  • 加了UNIQUE条件的不能为空
  • 码属性不能为空

4.空值的运算

【例3.82】找出选修1号课程的不及格的学生。

SELECT Sno
FROM SC
WHERE Grade<60 AND Cno='1';

查询结果不包括缺考的学生,因为他们的Grade是NULL;

【例3.83】找出选修1号课程的不及格的学生以及缺考的学生。

SELECT Sno
FROM SC
WHERE Grade<60 AND Cno='1'
UNION
SELECT Sno
FROM SC
WHERE Grade IS NULL AND Cno='1';
--或者
SELECT Sno
FROM SC
WHERE Cno='1' AND (Grade<60 OR Grade IS NULL);

注意AND 和 OR 的优先级。
在这里插入图片描述
没有不及格的学生,但201215003缺考。

视图

视图是虚表,是从一个或几个基本表(或视图)中导出来的表。只存放视图的定义,不存放相应的数据。基表是内里,视图是外部显示,基表数据发生变化后,视图数据也发生相应变化。

1.建立视图

语句:

CREATE VIEW
  <视图名>[(<列名>[,<列名>...])]
AS <子查询>
[WITH CHECK OPTION];

WITH CHECK OPTION用于视图更新时自动田间子查询中条件。
在执行该语句时,只是把视图的定义存放到数据字典中,并不执行其中的SELECT语句;当对视图进行查询时,在按照定义在基本表中将数据查出。CREATE只有定义,只有查询它,才会出现想要的数据。
组成视图的属性列可以全部省略,也可以全部指定。

  • 全部省略时,由子查询中SELECT的目标列组成。
  • 全部指定:
    1.某个目标列是聚集函数或列表达式(没有名字)
    2.多表连接时选出几个同名字段组成视图(避免混淆)
    3.需要为某个列启用新名字时(增强可读性)

基于一个表建立的视图:

【例3.84】建立信息系学生的视图

CREATE VIEW IS_Student
AS 
  SELECT Sno,Sname,Sdept
  FROM Student
  WHERE Sdept='IS';

在这里插入图片描述
行列子集视图:单个基本表导出,并只是去掉了某些行和某些列,但仍保留主属性的视图。
上题中的IS_Student就是一个行列子集视图。

【例3.85】建立信息系学生视图,并且要求进行修改和插入操作时,仍需保证该视图中只有信息系学生。

CREATE VIEW IS_Student
AS 
SELECT Sno,Sname,Sage
FROM   Student
WHERE  Sdept= 'IS'
WITH CHECK OPTION;

使用WITH CHECK OPTION完成,每次操作自动添加子查询中的条件,使得结果得以保证。

基于多个基本表建立的视图:

【例3.86】建立信息系选修了1号课程的学生的视图。

CREATE VIEW IS_S1(Sno,Sname,Grade)
AS
   SELECT Student.Sno,Sname,Grade
   FROM Student.SC
   WHERE Cno='1' AND Sdept = 'IS' 
         AND SC.Sno=Student.Sno;

在子查询中将多表连接。

基于视图的视图

【例3.87】建立信息系选修了1号课程且成绩在90分以上的学生视图。

CREATE VIEW IS_S2
AS
   SELECT *
   FROM IS_S1
   WHERE Grade >90;

该视图是基于IS_S1视图建立的。

【例3.88】定义一个反应学生出生年份的视图

CREATE  VIEW BT_S(Sno,Sname,Sbirth)
AS 
SELECT Sno,Sname,2020-Sage
FROM   Student;

给表达式2020-Sage命名为Sbirth.
在这里插入图片描述在这里插入图片描述

分组视图:
【例3.89】将学生的学号和平均成绩定义为一个视图

CREATE VIEW S_G(Sno,Gavg)
AS
   SELECT Sno,AVG(Grade)
   FROM SC
   GROUP BY Sno;

在这里插入图片描述
【发现问题】这里CREATE VIEW的语句不可以和下面SELECT *的语句同时选中执行,必须先创建后再做查询。

【例3.90】将Student表中所有女生记录定义为一个视图。

CREATE VIEW F_Student(F_Sno,name,sex,age,dept)
AS
   SELECT *
   FROM Student
   WHERE Ssex='女';

在这里插入图片描述
建立的几张视图在数据库中视图一栏下可以找到。
在这里插入图片描述

2.删除视图 —— DROP

语句:

DROP VIEW <视图名>[CASCADE];

从数据字典中删除了视图的定义,如果视图之上还有视图,CASCADE可以全部删除。
删除基表时,由该表导出的视图定义要用DROP VIEW显式删除。

【例3.91】删除视图S_G和视图IS_S1;

DROP VIEW S_G;
DROP VIEW IS_S1;

S_G成功删掉,但是IS_S1不能成功删掉,是因为IS_S2在IS_S1上建立。使用CASCADE可以一同删除。

3.查询视图

对于用户,查询基本表和查询视图相同。
RDBMS采用视图消解法对视图进行查询。

  1. 有效性检查
  2. 转换为等价的对基本表的查询
  3. 执行转化后的查询

【例3.92】在信息系学生的视图中找出年龄小于20岁的学生。

SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
--等价转换
SELECT Sno,Sage
FROM Student
WHERE Sdept='IS' AND Sage<20;

有些情况下,视图消解法不能生成正确的查询。
【例3.94】在S_G视图中查询平均成绩在90分以上的学生学号和平均成绩。

SELECT Sno,Gavg
FROM S_G
WHERE Gavg>=90;

SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90;
GROUP BY Sno;--错误

SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;--正确

视图消解法会把条件放到WHERE子句中,当条件中有聚集函数的时候就会产生错误。

该题还可以用基于派生表的查询完成:

SELECT *
FROM (SELECT Sno,AVG(Grade)
      FROM SC
      GROUP BY Sno)
      AS S_G(Sno,Gavg)
WHERE Gavg>=90;

4.更新视图UPDATE/INSERT/DELETE

【例3.95】将信息系学生视图IS_Student中学号为‘201215122’的学生姓名改为刘辰

UPDATE IS_Student
SET Sname='刘辰'
WHERE Sno='201215122';

--转换后
UPDATE Student
SET Sname='刘辰'
WHERE Sno='201215122' AND Sdept='IS';

刘晨是CS系的,所以没有改动。换一个人“刘a”
在这里插入图片描述在这里插入图片描述
!!!修改视图也会更改基本表中相应数据!!!

【例3.96】向IS_Student中插入一条新的学生记录,(‘201215129’,‘赵新’,20)

INSERT INTO IS_Student
VALUES('201215129','赵新',20);
--转换为
INSERT INTO Student
VALUES('201215129','赵新',NULL,20,'IS');

这里在SQL上实验发现,并不能将这条语句插入到IS_Student视图中,而且插入到原表Student表中的值中Sdept是NULL,而不是IS。因为没有指定系别,所以插入进去为NULL。这个实验可以看出,在视图中插入数据,可以插入到基本表中。但并不满足要求。
在这里插入图片描述
【例3.97】删除信息系学生视图中学号为‘201215129’学生的记录

DELETE
FROM IS_Student
WHERE Sno='201215129';

--转换后
DELETE
FROM Student
WHERE Sno='201215129' AND Sdept='IS';

下面赵新的数据,是我将Student表中他的Sdept改为IS后,在对IS_Student做查询,从而成功插入的。
在这里插入图片描述
删除后,基本表里面的相应记录也会被删掉。
在这里插入图片描述
有些视图是不可以被更新的,因为无法唯一地有意义地转换成对应基本表的更新
S_G视图就不能被更新,因为它含有聚集函数AVG(Grade),无法转换为对基本表的更新,因为基本表中没有这一属性的数据。
【例】

UPDATE S_G
SET Gavg=90
WHERE Sno='201215121';

会产生以下错误:
Update or insert of view or function ‘S_G’ failed because it contains a derived or constant field.

原因:
Gavg并不存在对应的基本表中的实际数据。

【心得】内容相对简单,但积攒起来也耗费不少时间。了解了SQL语句使用的一些小的注意事项以及视图与基本表的联系,如果不做实验,有些小的注意事项真的会忽视掉。质量方面,还算不错,作业与整理笔记共同完成,但是时间控制方面,仍然欠缺。效率仍待提高。

发布了10 篇原创文章 · 获赞 11 · 访问量 3612

猜你喜欢

转载自blog.csdn.net/fu_GAGA/article/details/105049184