Skip to content

插入数据

INSERT / 插入单行 / 插入多行 / 插入检索结果

前面一直在查数据,但数据从哪来?——当然是插进去的。这一章开始真正动手改数据。

INSERT 基础:插入一行

语法一眼就懂:

sql
INSERT INTO users (name, age, city, salary)
VALUES ('马十一', 24, '成都', 9000.00);

拆开看:

  • INSERT INTO users — 往哪张表里插
  • (name, age, city, salary) — 要填哪些列
  • VALUES (...) — 对应列的值

跑完 SELECT * FROM users; 就能看到多了一行,id 自动分配为 9。

列的顺序可以换

只要列名和值对应上就行:

sql
INSERT INTO users (city, name, salary, age)
VALUES ('重庆', '何十二', 11000.00, 28);

省略列名

如果 VALUES 给的值和表定义的列顺序完全一致,可以省掉列名:

sql
INSERT INTO users
VALUES (11, '丁十三', 31, '武汉', 7500.00);
--      注意 id 也得手动给(虽然平时 AUTO_INCREMENT 自动填)

⚠️ 不建议省列名。表结构一改(比如加了一列),没写列名的 INSERT 直接报废。老老实实写明列名,安全第一。

省略列:用默认值

不是每列都必须给值。不写的列,MySQL 会用默认值或 NULL 来填:

sql
INSERT INTO users (name, city, salary)
VALUES ('林十四', '南京', 8200.00);

age 没写,这一行的 age 就是 NULL。

哪些列可以不写?满足以下任一条件即可:

  • 列定义了 DEFAULT
  • 列允许 NULL

idAUTO_INCREMENT,不用写——MySQL 自动分配。

一次插入多行

一行一行插太慢。VALUES 后面接多组括号,逗号隔开:

sql
INSERT INTO users (name, age, city, salary) VALUES
('马十一', 24, '成都',  9000.00),
('何十二', 28, '重庆', 11000.00),
('丁十三', 31, '武汉',  7500.00);

三行一次性写入,比单条 INSERT 跑三次快得多。

💡 批量插入时,一条 INSERT 比多条 INSERT 性能好很多——减少网络来回次数。

插入检索出来的数据

INSERT 和 SELECT 可以组合使用,把查出来的结果直接插到另一张表。

场景:创建一个 users_backup 表,把北京员工备份过去。

sql
-- 先建备份表(结构一样)
CREATE TABLE users_backup (
    id      INT           AUTO_INCREMENT PRIMARY KEY,
    name    VARCHAR(20)   NOT NULL,
    age     INT,
    city    VARCHAR(50),
    salary  DECIMAL(8,2)
);

-- 把北京员工的数据插进去
INSERT INTO users_backup (name, age, city, salary)
SELECT name, age, city, salary
FROM users
WHERE city = '北京';

一次性把 3 行北京员工数据复制到了 users_backup 表。这就是 INSERT SELECT——不用先把数据读出来再插,MySQL 内部直接搬运。

📝 INSERT SELECT 的列数和类型规则和 UNION 一样:列数一致,类型兼容,列名无所谓。

插入时的常见错误

主键冲突

sql
INSERT INTO users (id, name, city, salary)
VALUES (1, '重复了', '北京', 5000.00);
-- ERROR: Duplicate entry '1' for key 'PRIMARY'

id=1 已经存在,主键不能重复。要么不写 id 让 MySQL 自动分配,要么用 INSERT IGNOREON DUPLICATE KEY UPDATE(后面讲)。

类型不匹配

sql
INSERT INTO users (name, age, city, salary)
VALUES ('测试', '不是数字', '北京', 5000.00);
-- ERROR: Incorrect integer value: '不是数字' for column 'age'

age 是 INT,塞字符串进去 MySQL 不认。

NOT NULL 列不给值

sql
INSERT INTO users (age, city, salary) VALUES (25, '北京', 5000.00);
-- ERROR: Field 'name' doesn't have a default value

name 定义了 NOT NULL 又没有默认值,必须给值。

安全写法建议

sql
-- ✅ 好的写法:列名写全(除了自增主键),值一一对应
INSERT INTO users (name, age, city, salary)
VALUES ('新人', 26, '长沙', 8800.00);

-- ❌ 偷懒的写法:不写列名,出问题了都不知道哪列对不上
INSERT INTO users VALUES (15, '新人', 26, '长沙', 8800.00);

小结

增删改的第一步——插入数据,记住这几个要点:

  1. INSERT INTO 表(列) VALUES(值) — 基本句式,列和值一一对应
  2. 写列名是好习惯 — 不写列名看似省事,表结构一变就炸
  3. 一次插多行VALUES (行1), (行2), (行3) 性能好很多
  4. INSERT SELECT 批量搬运 — 把查询结果直接插入另一张表
  5. NOT NULL 列必须给值 — 否则直接报错,AUTO_INCREMENT 列不用管

💡 插入是最简单的写操作,但从这章开始你真正在改数据了——养成"先 SELECT 确认、再 INSERT"的好习惯。

自主练习

  1. users 表插入一条自己的信息
  2. 一次插入 3 条新员工,城市各不相同
  3. 新建一张 users_copy 表(和 users 结构一样),用 INSERT SELECT 把所有工资 > 10000 的人复制过去
  4. 试一下不写 age 列会怎样?不写 name 列会怎样?

建表语句参考 02.安装与环境 里的 CREATE TABLE users,改个表名就行。


评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8