大型数据库管理系统技术、应用与实例分析:SQL Server 2005
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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 课名 = '数据库原理'
    )
)