位置:首页 > SQL > SQL INSERT语句一次插入多行数据的方法与写法

SQL INSERT语句一次插入多行数据的方法与写法

时间:2026-08-21  |  作者:星河游者  |  阅读:0

一次INSERT插入多行数据的正确写法是单条语句、多组圆括号VALUES用英文逗号分隔,字段顺序与数量须严格一致,主流数据库均支持,Oracle旧版本除外。

SQL INSERT语句如何一次插入多行数据

INSERT INTO 语句完全支持一次插入多行,只要用对语法——不是写多个 INSERT,也不是拼 UNION ALL,而是单条语句、多组 VALUES

VALUES 后面跟多组圆括号,用英文逗号分隔

这种写法是最核心的,除了Oracle(12c及以后版本才部分支持,旧版必须拆成多条语句),所有主流数据库(MySQL、PostgreSQL、SQL Server、SQLite)都原生支持。

常见错误是把下面这种写法当成合法 SQL:

INSERT INTO users (name, email) VALUES ('Alice', 'a@example.com');
INSERT INTO users (name, email) VALUES ('Bob', 'b@example.com');

这其实是两条独立语句,在多数客户端或 ORM 中会因分号或换行被截断,只执行第一行;在严格模式下直接报错。

  • 正确写法:所有值组写在同一个 VALUES 后,每组用 () 包裹,组间用英文逗号连接
  • 列名列表只出现一次,必须与每组值的顺序、数量、类型严格对应
  • 字符串要用单引号,数字不加引号,NULL 直接写,不要加引号

PostgreSQL 对类型和长度更敏感

PostgreSQL 在多行 INSERT 中会逐行校验类型,比如你写 (1, '2024-01-01'), (2, 'invalid-date'),整条语句会失败,哪怕第一行完全合法。

MySQL 相对宽松,可能只警告或隐式转换(如把字符串转为数字),但后果不可控。

  • 建议显式 cast:比如 TO_DATE('2024-01-01', 'YYYY-MM-DD')(PostgreSQL)或 STR_TO_DATE('2024-01-01', '%Y-%m-%d')(MySQL)
  • 避免混合类型:不要在同列位置混用 '1'2,即使数值相同
  • 单次插入建议 ≤ 1000 行;超过后容易触发内存限制或超时,尤其在远程连接或低配实例上

自增主键和默认值怎么处理

要是表有 id SERIAL(PostgreSQL)或者 id INT AUTO_INCREMENT(MySQL),那这列完全是可以省略的——不过要注意,所有对应位置的值也得一并省略,而且列名列表里绝不能包含它。

例如:INSERT INTO users (name, email) VALUES ('A', 'a@b.c'), ('B', 'b@b.c'); —— 这里没提 id,数据库自动分配。

  • 如果列定义了 DEFAULT(如 created_at TIMESTAMP DEFAULT NOW()),也不用写,留空即可
  • 但不能写成 (DEFAULT, 'A', 'a@b.c'),除非你明确需要触发默认值计算(少数场景有用)
  • 如果某列允许 NULL 且无默认值,可直接写 NULL,不要留空或写空字符串

批量插入性能和事务边界

单条多行 INSERT 比循环执行 N 条单行 INSERT 快 5–10 倍,因为减少了网络往返和解析开销。但它仍是一次 DML 操作,受事务控制。

这意味着:如果插入第 500 行失败,前面 499 行也全部回滚(除非你用了 ON CONFLICT DO NOTHINGINSERT IGNORE 等容错语法)。

  • 生产环境大批量导入,建议分批(如每 500 行一个事务),避免锁表太久或 WAL 日志暴涨
  • 不要把整个 CSV 一次性塞进一条 INSERT——超过 5000 行就该切片
  • 注意字符集:如果数据含 emoji 或特殊符号,确保连接层和表字段都是 utf8mb4,否则可能截断或报错
真正容易被忽略的是 Oracle 兼容性——如果你的代码要跑在 Oracle 11g/12c 早期版上,INSERT INTO ... VALUES (...), (...) 是无效语法,必须改用 INSERT ALL 或拆成多条语句。其他数据库基本没这个问题。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多