Skip to content

插入、更新与删除

插入数据

在使用数据库之前,数据库中必须要有数据,MySQL 中使用 INSERT 语句向数据库表中插入新的数据记录。
可以插入的方式有插入完整的记录、插入记录的一部分、插入多条记录、插入另一个查询的结果:

为表的所有字段插入数据

使用基本的 INSERT 语句插入数据要求指定表名称和插入到新纪录中的值。基本语法格式为:

1
2
INSERT INTO table_name (column_list)
VALUES (value_list);

注意,使用该语句时字段列和数据值的数量必须相同

创建样例表 person:

1
2
3
4
5
6
7
CREATE TABLE person (
    id  INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name  CHAR(40) NOT NULL DEFAULT '',
    age  INT NOT NULL DEFAULT 0,
    info  CHAR(50) NULL,
    PRIMARY KEY (id)
);

向表中所有字段插入值的方法有两种:
一种是指定所有字段名,另一种是完全不指定字段名

例: 在 person 表中,插入一条新纪录,id 值为 1,name 值为 Green,age 值为 21, info 值为 Lawyer:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
INSERT INTO person (id,name,age, info)
VALUES (1, 'Green', 21, 'Lawyer');

SELECT * FROM person;
+----+-------+-----+--------+
| id | name  | age | info   |
+----+-------+-----+--------+
|  1 | Green |  21 | Lawyer |
+----+-------+-----+--------+
1 row in set (0.01 sec)

INSERT 语句后面的列名称顺序可以不是 person 表定义时的顺序。
即插入数据时,不需要按照表定义的顺序插入,只要保证值的顺序与列字段的顺序相同就可以

例: 在 person 表中,插入一条新纪录,id 值为 2,name 值为 Suse,age 值为 22,info 值为 dancer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
INSERT INTO person(age, name, id, info)
VALUES
    (22, 'Suse', 2, 'dancer');

SELECT * FROM person;
+----+-------+-----+--------+
| id | name  | age | info   |
+----+-------+-----+--------+
|  1 | Green |  21 | Lawyer |
|  2 | Suse  |  22 | dancer |
+----+-------+-----+--------+
2 rows in set (0.00 sec)

使用 INSERT 插入数据时,允许列名称列表 column_list 为空,此时,值列表中需要为表的每一个字段指定值,并且值的顺序必须和数据表中字段定义时的顺序相同

例: 在 person 表中,插入一条新记录,id 值为 3,name 值为 Mary,age 值为 24,info 值为 Musician

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
INSERT INTO person
VALUES
    (3, 'Mary', 24, 'Musician');

SELECT * FROM person;
+----+-------+-----+----------+
| id | name  | age | info     |
+----+-------+-----+----------+
|  1 | Green |  21 | Lawyer   |
|  2 | Suse  |  22 | dancer   |
|  3 | Mary  |  24 | Musician |
+----+-------+-----+----------+
3 rows in set (0.00 sec)

提示:
虽然使用 INSERT 插入数据时可以忽略插入数据的列名称,但是值如果不包含列名称,那么 VALUES 关键字后面的值不仅要求完整而且顺序必须和表定义时列的顺序相同。
如果表的结构被修改,对列进行增加、删除或者位置改变操作,这些操作将使用这种方式插入数据时的顺序也同时改变。
如果指定列名称,则不会受到表结构改变的影响

为表的指定字段插入数据

为表的指定字段插入数据,就是 INSERT 语句中只向部分字段中插入值,而其他字段的值为表定义时的默认值

例: 在 person 表中,插入一条新纪录,name 值为 Willam,age 值为 20,info 值为 sportsman:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
INSERT INTO person (name, age, info)
VALUES ('Willam', 20, 'sports man');

SELECT * FROM person;
mysql> SELECT * FROM person;
+----+--------+-----+------------+
| id | name   | age | info       |
+----+--------+-----+------------+
|  1 | Green  |  21 | Lawyer     |
|  2 | Suse   |  22 | dancer     |
|  3 | Mary   |  24 | Musician   |
|  4 | Willam |  20 | sports man |
+----+--------+-----+------------+
4 rows in set (0.01 sec)

可以看到插入记录成功。如查询结果显示,该 id 字段自动添加了一个整数值 4.
在这里,id 字段为表的主键,不能为空,系统会自动为该字段插入自增的序列值。

下面的例子说明在没有指定列字段时,插入默认值:

例: 在 person 表中,插入一条新记录,name 值为 laura,age 为 25

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
INSERT INTO person (name, age)
VALUES ('Larura', 25);

mysql> SELECT * FROM person;
+----+--------+-----+------------+
| id | name   | age | info       |
+----+--------+-----+------------+
|  1 | Green  |  21 | Lawyer     |
|  2 | Suse   |  22 | dancer     |
|  3 | Mary   |  24 | Musician   |
|  4 | Willam |  20 | sports man |
|  5 | Larura |  25 | NULL       |
+----+--------+-----+------------+
5 rows in set (0.00 sec)

同时插入多条记录

INSERT 语句可以同时向数据表中插入多条记录,插入时指定多个值列表,每个值列表之间用逗号分隔开

1
2
INSERT INTO table_name (colum_list)
VALUES (value_list1), (value_list2), ..., (value_listn);

例: 在 person 表中,在 name、age 和 info 字段插入值,同时插入 3 条新纪录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
INSERT INTO person (name, age, info)
VALUES
('Evans', 27, 'secretary'),
('Dale', 22, 'cook'),
('Edlson', 28, 'singer');

Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM person;
+----+--------+-----+------------+
| id | name   | age | info       |
+----+--------+-----+------------+
|  1 | Green  |  21 | Lawyer     |
|  2 | Suse   |  22 | dancer     |
|  3 | Mary   |  24 | Musician   |
|  4 | Willam |  20 | sports man |
|  5 | Larura |  25 | NULL       |
|  6 | Evans  |  27 | secretary  |
|  7 | Dale   |  22 | cook       |
|  8 | Edlson |  28 | singer     |
+----+--------+-----+------------+
8 rows in set (0.00 sec)

使用 INSERT 同时插入多条记录时,MySQL 会返回一些在执行单行插入时没有的额外信息,这些信息的含义如下:

  • Records: 表明插入的记录条数
  • Duplicates: 表名插入时被忽略的记录,原因可能时这些记录包含了重复的主键值
  • Warnings: 表明有问题的的数据值,例如发生数据类型转换

例: 在 person 表中,不指定插入列表,同时插入 2 条新纪录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
INSERT INTO person
VALUES 
    (9, 'Harry', 21, 'magician'),
    (NULL, 'Harrist', 19, 'planist');

Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

+----+---------+-----+------------+
| id | name    | age | info       |
+----+---------+-----+------------+
|  1 | Green   |  21 | Lawyer     |
|  2 | Suse    |  22 | dancer     |
|  3 | Mary    |  24 | Musician   |
|  4 | Willam  |  20 | sports man |
|  5 | Larura  |  25 | NULL       |
|  6 | Evans   |  27 | secretary  |
|  7 | Dale    |  22 | cook       |
|  8 | Edlson  |  28 | singer     |
|  9 | Harry   |  21 | magician   |
| 10 | Harrist |  19 | planist    |
+----+---------+-----+------------+
10 rows in set (0.00 sec)

由结果可以看到,INSERT 语句执行后,person 表中添加了 2 条记录,与前面介绍单个 INSERT 语法不同,person 表名后面没有指定插入字段列表,因此 VALUES 关键字后面的多个值列表都要为每一条记录的每一个字段列指定插入值,并且这些值的顺序必须和 person 表中字段定义的顺序相同,带有 AUTO_INCREMENT 属性的 id 字段插入 NULL 值,系统会自动为该字段插入唯一的自增编号。

提示:

一个同时插入多行记录的 INSERT 语句等同于多个单行插入的 INSERT 语句,
但是一次插入多行的 INSERT 语句在处理过程中效率更高。
因为 MySQL 执行单条 INSERT 语句插入多行数据比使用多条 INSERT 语句快,
所以在插入多条记录时最好选择使用单条 INSERT 语句的方式插入。

将查询结果插入到表中

INSERT 语句用来给数据表插入记录时指定插入记录的列值。
INSERT 还可以将 SELECT 语句查询的结果插入到列表中,如果想要从另外一个表中合并个人信息到 person 表,不需要把每一条记录的值一个一个输入,只需要使用一条 INSERT 语句和一条 SELECT 语句组成的组合语句即可快速地从一个或多个表中向一个表中插入多行:

1
2
INSERT INTO table_name1 (column_list1)
SELECT (column_list2) FROM table_name2 WHERE (condition);

column_list1 和 column_list2 必须字段个数相同,数据类型相同

更新数据

表中有数据之后,接下来可以对数据进行更新操作,MySQL 中使用 UPDATE 语句更新表中的记录,可以更新待定的行或者同时更新所有的行。

1
2
3
UPDATE table_name
SET column_name1 = value1, column_name2 = value2,..., column_namen = valuen
WHERE (condition);

例: 在 person 表中,更新 id 值为 10 的记录,将 age 字段值改为 15,将 name 字段改为 LiMing:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
UPDATE person
SET age = 15, name = 'LiMing'
WHERE id = 10;

Query OK, 1 row affected (0.09 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM person WHERE id = 10;
+----+--------+-----+---------+
| id | name   | age | info    |
+----+--------+-----+---------+
| 10 | LiMing |  15 | planist |
+----+--------+-----+---------+
1 row in set (0.00 sec)

提示:
保证 UPDATE 以 WHERE 子句结束,通过 WHERE 子句指定被更新的记录所需要满足的条件,如果忽略 WHERE 子句,MySQL 将更新表中所有的行

例: 在 person 表中,更新 age 为 19 到 22 的记录,将 info 字段值都改为 student:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
UPDATE person 
SET info = 'student'
WHERE age BETWEEN 19 AND 22;

Query OK, 5 rows affected (0.01 sec)
Rows matched: 5  Changed: 5  Warnings: 0

mysql> SELECT * FROM person;
+----+--------+-----+-----------+
| id | name   | age | info      |
+----+--------+-----+-----------+
|  1 | Green  |  21 | student   |
|  2 | Suse   |  22 | student   |
|  3 | Mary   |  24 | Musician  |
|  4 | Willam |  20 | student   |
|  5 | Larura |  25 | NULL      |
|  6 | Evans  |  27 | secretary |
|  7 | Dale   |  22 | student   |
|  8 | Edlson |  28 | singer    |
|  9 | Harry  |  21 | student   |
| 10 | LiMing |  15 | planist   |
+----+--------+-----+-----------+
10 rows in set (0.00 sec)

删除数据

从数据表中删除数据使用 DELECT 语句,DELETE 语句允许 WHERE 子句指定删除条件:

1
DELETE FROM table_name [WHERE <condition>];

如果没有 WHERE 子句,DELETE 语句将删除表中的所有记录

提示:

如果想删除表中的所有记录,还可以使用 TRUNCATE TABLE 语句。
TRUNCATE 将直接删除原来的表,并重新创建一个表,其语法结构为 TRUNCATE TABLE table_name。
TRUUNCATE 直接删除表而不是删除记录,因此执行速度比 DELETE 快

为表增加计算列

什么叫计算列呢?简单来说就是某一列的值是通过别的计算得来的。
例如,a 列值为 1,b 列值为 2,c 列不需要手动插入,定义 a+b 的结果为 c 的值,那么 c 就是计算列,是通过别的列计算得来的

增加计算列的语法格式如下:

1
2
3
col_name data_type [GENERATED ALWAYS] AS (expression)
    [VIRTUAL | STORED] [UNION [KEY]] [COMMENT comment]
    [NOT NULL | NULL] [PRIMARY KEY];

在 MySQL 8.0 中,CREATE TABLE 和 ALTER TABLE 中都支持增加计算列。

例: