## 1.9 数据操纵

数据操纵包括三种操作：向表中添加若干行数据、修改表中的数据和删除表中的若干行数据。在SQL中分别对应INSERT、UPDATE和DELETE三类语句。


### 1.9.1 数据插入

当表结构定义好之后，就能够往表里插入数据。SQL的数据插入语句INSERT通常有两种形式，一种是插入元组，另一种是插入子查询结果。本小节主要介绍插入元组的INSERT语句，其基本格式如下：

```SQL
INSERT 
INTO <表名> [（<属性列1> [，<属性列2>] ...）]
VALUES (<常量1> [，<常量2>]...);
```

INTO子句中指定要插入数据的基础表以及要插入的属性列名，VALUES子句指定插入元组的各属性值，其中常量1为新元组属性列1的值，常量2为新元组属性列2的值，......。
此外，INTO子句中可以不指定任何属性列名，那么，VALUES子句中新插入的元组必须在每个属性列上均有值，且要按照表定义中属性列的顺序。

```SQL
[例1.19] 向Student表中插入一个新学生元组（学号：2022013，姓名：宇轩，性别：男，年龄：20，系：计算机）。
INSERT 
INTO Student
VALUES('2022013','宇轩','男',20,'计算机'); 
另一种SQL表示 
INSERT 
INTO Student(Sno, Sname,Age, Gender,Dept)
VALUES('2022013','宇轩',20,'男','计算机'); 
```
第一种SQL表示中，INTO子句中未指定任何属性列名时，VALUES子句中的新插入的属性列值要与表定义的属性列一致，否则将出错。第二种SQL表示中，INTO子句中指定了属性列名，属性的顺序可以和表定义的顺序不一致，但是VALUES中插入的属性值要与INTO中指定的属性列名对应。另外，VALUES子句中字符串常数要用单引号（英文符号）括起来。

```SQL
[例1.20] 向SC表中插入一条选课记录（学号：2022013，课程号：1，成绩：NULL）。
INSERT <br>
INTO SC(Sno, Cno)
VALUES('2022013','1'); 
另一种SQL表示 
INSERT 
INTO SC
VALUES('2022013','1',NULL); <br>
```

第一种SQL表示中，INTO子句没有指定SC表中的Grade属性列，关系数据库管理系统将在新插入元组的Grade列上自动地赋空值。需要注意的是，表定义时说明了NOT NULL的属性列不能取空值，否则会出错。第二种SQL表示中，INTO子句没有指定SC表的任何属性列，那么VALUES子句中新元组每个属性列上均要有值，因此Grade列上要明确给出空值。

此外，INSERT还支持一次插入多个元组。

```SQL
[例1.21] 向SC表中插入三条选课记录。
INSERT 
INTO SC(Sno,Cno)
VALUES('2022013','1'), ('2022001','3'),('2022191','2'); 
```

### 1.9.2 数据修改

数据的修改操作又称为数据更新。SQL的更新语句UPDATE的基本格式为：

```SQL
UPDATE <表名>
SET <列名1>=<表达式1> [,<列名2>=<表达式2>...]
[WHERE <条件表达式>]
```
其功能是修改指定表中满足WHERE子句条件的元组。SET子句中<表达式>的值用于取代相应的属性列值。如果省略WHERE子句，则表示修改表中的所有元组。

```SQL
[例1.22] 将学生2022013的年龄改为19岁。
UPDATE Student
SET Age = 19
WHERE Sno = '2022013';
[例R1.21] 将所有男生的年龄增加1岁。
UPDATE Student
SET Age = Age + 1
WHERE Gender = '男'; 
```

### 1.9.3 数据删除

删除语句DELETE的基本格式为：

```SQL
DELETE
FROM <表名>
[WHERE <条件表达式>]
```

该功能是从指定表中删除满足WHERE子句条件的所有元组。如果省略WHERE子句则表示删除表中的全部元组，但表的定义仍在字典中。也就是说，DELETE语句删除的是表中的数据，而不是关于表的定义。

```SQL
[例1.23] 删除学号为2022013的学生信息。
DELETE
FROM Student
WHERE Sno = '2022013';
[例1.24] 删除所有学生的选课记录。
DELETE
FROM SC;
```

### 练习题

**1.**  思考题：如果我们在属性A上定义Primary Key或Unique这样的约束，那么数据库将要求表中的任何一个元组在A上取值都是唯一的。也就是说，当我们往表中重复插入A值时，数据库将立即感知到，并禁止我们这样做。请问：数据库是如何感知我们往表中重复插入A值的？

[**上一页<<**](chapter1.8-R.md) | [**>>下一页**](chapter1.10-R.md)
