5.2 表数据编辑
表数据编辑又称数据更新,包括插入数据、修改数据和删除数据三类命令。插入数据要用INSERT命令,修改数据要用UPDATE命令,删除数据要用DELETE命令。下面分别进行介绍。
5.2.1 插入数据
1.插入单个元组
SQL语言用INSERT…VALUES语句向关系表添加一条元组,其一般格式如下:
INSERT [INTO] <表名> [ (<列名>[,…n]) ] VALUES (<表达式>[,…n])
注意:
(1)未出现在列名列表中的列插入时取空值;
(2)VALUES子句中的表达式数量必须和INSERT后面的列名数量相等,表达式的数据类型必须和对应列的数据类型相兼容;
(3)若关系表中存在定义为NOT NULL的列,则该列的列名必须出现在列名列表中,该列的值也必须出现在VALUES子句中且不能为空;
(4)如果省略列名列表,则VALUES子句必须指定所有列的值。
【例5-40】插入一条选课记录('S060102','010201')到选课表中。
INSERT INTO 选课表 (学号,开课号) VALUES ('S060102','010201')
新插入的记录在成绩列上取空值。
【例5-41】将新生记录('S060111',NULL,'陈向东','男',NULL,'上海','计算机','信息学院',158)插入学生表中。
INSERT INTO 学生表 VALUES ('S060111',NULL,'陈向东','男',NULL,'上海','计算机','信息学院', 158)
本例由于省略了列名列表,因此VALUES子句给出了所有列的值。
2.插入子查询的结果
SQL语言用INSERT…SELECT语句将子查询的结果插入到关系表中,其一般格式如下:
INSERT [INTO] <表名> [ (<列名>[,…n]) ] SELECT语句
注意:
(1)未出现在列名列表中的列插入时取空值;
(2)SELECT语句中的目标列表达式数量必须和INSERT后面的列名数量相等,目标列表达式的数据类型必须和对应列的数据类型相兼容;
(3)若关系表中存在定义为NOT NULL的列,则该列的列名必须出现在列名列表中,该列的值也必须出现在SELECT语句的目标列中,且不能为空;
(4)如果省略列名列表,则SELECT语句必须指定所有列的值。
【例5-42】对每一个专业,求学生的平均累计学分,并把结果存入一张表中。
这道题分两个步骤求解。首先用CREATE TABLE语句建立一个含两个属性列的表主修专业,一列存放专业名,另一列存放主修该专业的学生的平均累计学分。然后对学生表按专业分组并求每个组平均累计学分,再把专业名和平均累计学分存入主修专业表中。
CREATE TABLE 主修专业 ( 专业 CHAR(20),avgpa INT) INSERT INTO 主修专业(专业,avgpa) SELECT 专业,AVG(累计学分) FROM 学生表 GROUP BY 专业
3.使用SELECT…INTO语句进行数据插入
用SELECT…INTO语句进行数据插入时,系统首先自动创建一个新表,新表的结构由目标列表达式的特性定义,然后将 SELECT语句的结果集插入这个新表。其一般格式如下:
SELECT <目标列>[,…n] INTO <新表名> [SELECT语句的其他子句]
注意:当目标列是计算列时,必须为它起别名。
实际上,SELECT … INTO语句和INSERT…SELECT语句的功能是相同的,不同之处是INSERT…SELECT语句需要由用户建立新表,而SELECT…INTO语句则由系统自动建立这张新表。
【例5-43】用SELECT … INTO语句改写例5-42。
SELECT 专业,AVG(累计学分) AS 平均累计学分 INTO 主修专业 FROM 学生表 GROUP BY 专业
5.2.2 修改数据
1.数据修改语句概述
SQL语言用UPDATE语句对表中的数据进行修改。
语法格式:
UPDATE <表名> SET <列名> = <表达式>[,…n] [ FROM <表名>[,…n] ] [WHERE <条件>]
参数说明:
(1)UPDATE语句用来修改指定表中满足WHERE条件(即修改条件)的元组。修改方法是用SET子句中<表达式>的值取代相应列的值。
(2)修改条件的构造方法和SELECT语句中WHERE条件的构造方法完全相同,例如,修改条件不仅可以直接使用UPDATE关键字后面的表所包含的列,也可以通过引入FROM子句直接使用其他表所包含的列,甚至可以将复杂的子查询嵌入修改条件中。
2.修改给定表的所有行
如果省略WHERE子句(此时FROM子句不起任何作用,通常同时省略),则UPDATE语句将修改表的所有行。
【例5-44】将所有学生的累计学分增加3分。
UPDATE 学生表 SET 累计学分=累计学分+3
3.基于给定表修改某些行
如果省略FROM子句,但含有WHERE子句,则UPDATE语句将修改满足修改条件的行,但是此时的修改条件只能直接使用UPDATE后面的表所包含的列。
【例5-45】将计算机专业所有女生的籍贯改为“杭州”,累计学分增加3分。
UPDATE 学生表 SET 累计学分=累计学分+3,籍贯='杭州' WHERE 专业 = '计算机' AND 性别 = '女'
4.基于其他表修改某些行
如果UPDATE语句中的修改条件需要使用其他表的列,就要用FROM子句将这些表引入到UPDATE语句中,此时的修改条件不仅能够直接使用UPDATE后面的表所包含的列,也能够直接使用FROM后面的表所包含的列。
【例5-46】将计算机专业所有学生的数据库原理课程的成绩增加10分。
UPDATE 选课表 SET 成绩 = 成绩+10 FROM 开课表 AS O,课程表 AS C,学生表 AS S WHERE 专业 = '计算机' AND 课名 = '数据库原理' AND C.课号 = O.课号 AND O.开课号 = 选课表.开课号 AND 选课表.学号 = S.学号
5.使用子查询修改某些行
UPDATE语句中的修改条件还可以通过嵌入子查询进行构造。由于子查询的嵌套层数没有限制,并且其中的WHERE条件可以直接使用UPDATE后面的表所包含的列、外层FROM后面的表所包含的列、子查询中FROM后面的表所包含的列,因此可以表达非常复杂的修改条件。
【例5-47】用子查询构造例5-46的修改条件,实现相同的修改功能。
UPDATE 选课表 SET 成绩 = 成绩+10 FROM 学生表 AS S WHERE 专业 = '计算机' AND 选课表.学号 = S.学号 AND 开课号 IN ( SELECT 开课号 FROM 开课表 WHERE 课号 IN ( SELECT 课号 FROM 课程表 WHERE 课名 = '数据库原理' ) )
5.2.3 删除数据
1.数据删除语句概述
SQL语言用DELETE语句删除给定表中的某些行。
语法格式:
DELETE [FROM] <目标表名> [FROM <表名>[,…n] ] [WHERE <条件>]
参数说明:
(1)DELETE语句用来删除目标表中满足WHERE条件(即删除条件)的元组。
(2)删除条件的构造方法和SELECT语句中WHERE条件的构造方法完全相同,例如,删除条件不仅可以直接使用目标表所包含的列,也可以通过引入FROM子句直接使用其他表所包含的列,甚至可以将复杂的子查询嵌入删除条件中。
注意,DELETE语句中有两个FROM关键字。第一个FROM关键字可以省略,用来指定目标表。第二个FROM关键字用来指定FROM子句。
2.删除目标表的所有行
如果省略WHERE子句(此时FROM子句不起任何作用,通常同时省略),则DELETE语句将删除目标表的所有行,即将目标表清空。
【例5-48】将学生表清空。
DELETE FROM 学生表
此外,还可以用TRUNCATE TABLE语句来清空目标表,其格式如下:
TRUNCATE TABLE <目标表名>
TRUNCATE TABLE语句的执行速度通常要比DELETE语句快,因为TRUNCATE TABLE语句是不记录日志的操作,因此,由它删除的数据将无法恢复。
3.基于目标表删除某些行
如果省略FROM子句,但含有WHERE子句,则DELETE语句将删除满足删除条件的行,但是此时的删除条件只能直接使用目标表所包含的列。
【例5-49】从学生表中删除计算机专业所有女生的信息。
DELETE FROM 学生表 WHERE 专业 = '计算机' AND 性别 = '女'
4.基于其他表删除某些行
如果DELETE语句中的删除条件需要使用其他表的列,就要用FROM子句将这些表引入到DELETE语句中,此时的删除条件不仅能够直接使用目标表所包含的列,也能够直接使用FROM子句中的表所包含的列。
【例5-50】从选课表中删除计算机专业所有学生对数据库原理课程的选修信息。
DELETE FROM 选课表 FROM 开课表 AS O,课程表 AS C,学生表 AS S WHERE 专业 = '计算机' AND 课名 = '数据库原理' AND C.课号 = O.课号 AND O.开课号 = 选课表.开课号 AND 选课表.学号 = S.学号
5.使用子查询删除某些行
DELETE语句中的删除条件还可以通过嵌入子查询进行构造。由于子查询的嵌套层数没有限制,并且其中的WHERE条件可以直接使用目标表所包含的列、外层FROM子句中的表所包含的列,以及子查询FROM子句中的表所包含的列,因此可以表达非常复杂的删除条件。
【例5-51】用子查询构造例5-50的删除条件,实现相同的删除功能。
DELETE FROM 选课表 FROM 学生表 AS S WHERE 专业 = '计算机' AND 选课表.学号 = S.学号 AND 开课号 IN ( SELECT 开课号 FROM 开课表 WHERE 课号 IN ( SELECT 课号 FROM 课程表 WHERE 课名 = '数据库原理' ) )