Oracle不支持标准INSERT INTO ... VALUES(...),(...)语法,必须使用INSERT ALL或INSERT...SELECT UNION ALL方式实现多行插入,且结尾需强制添加SELECT * FROM DUAL。

直接用 INSERT INTO ... VALUES (...), (...), (...) 就行,所有主流数据库(MySQL、PostgreSQL、SQL Server、SQLite)都支持,Oracle 是例外。
VALUES 列表写法:括号之间用英文逗号分隔
这是最通用、最推荐的方式。核心是只写一次 INSERT INTO 和列名,后面跟多组圆括号包裹的值,每组之间用英文逗号连接。
- 列名列表必须明确写出,且只出现一次:
INSERT INTO users (name, age, status) - 每组
VALUES的字段顺序和数量必须与列名列表严格一致 - 字符串用单引号,
NULL不加引号,数字不加引号:VALUES ('Alice', 28, 'active'), (NULL, 35, 'inactive') - 如果某列有默认值,显式写
DEFAULT更安全,别留空:VALUES ('log1', DEFAULT), ('log2', NOW())
PostgreSQL 和 MySQL 在类型校验上差异明显
语法一样,但 PostgreSQL 对类型匹配更苛刻,容易踩坑。
- 把字符串
'123'插入INT列:PostgreSQL 直接报错ERROR: column "age" is of type integer but expression is of type text;MySQL 默认可能隐式转成整数 - MySQL 在开启
STRICT_TRANS_TABLES模式后行为会接近 PostgreSQL,也会报错 - 别依赖自动转换——显式 CAST 或提前清洗数据更可靠,比如写成
CAST('123' AS INTEGER)(PostgreSQL)或CONVERT(INT, '123')(SQL Server)
Oracle 怎么办?它不支持标准 VALUES 多行
Oracle 是主流数据库里唯一不支持 VALUES (...), (...) 语法的。得换写法。
- 用
INSERT ALL:每行一个INTO子句,结尾必须跟SELECT * FROM DUAL - 或者用
INSERT INTO ... SELECT ... UNION ALL SELECT ...,每条SELECT后都要加FROM DUAL - 示例:
INSERT ALL INTO sales VALUES(1,1,'High') INTO sales VALUES(2,2,'Medium') SELECT * FROM DUAL; - 注意:这种写法在 Oracle 中性能不如批量绑定变量,大量数据建议走
SQL*Loader或应用层批量提交
插太多行会卡住或失败
不是语法限制,而是数据库底层配置在起作用。
- MySQL 的
max_allowed_packet默认约 4MB,插 5000 行长字符串很容易超限 - PostgreSQL 可能因
statement_timeout或内存不足中断执行 - 单条
INSERT建议控制在 1000 行以内;超过就拆成多个语句,比调大服务端参数更稳妥 - 真正大批量(万级以上)优先用专用导入方式:
LOAD DATA INFILE(MySQL)、COPY(PostgreSQL)、BULK INSERT(SQL Server)
最容易被忽略的是 Oracle 的语法隔离——其他库写熟了的人一换 Oracle 就卡在 VALUES 报错,其实不是不会写,是根本没这语法。另外,类型隐式转换在开发环境看似正常,上线到 PostgreSQL 或严格模式 MySQL 就崩,这类问题往往要等联调才暴露。

















