CSV 转 SQL 实战:从表格生成 INSERT 语句批量导入数据库
把带表头的 CSV 转成可执行的 CREATE TABLE 和 INSERT 语句,讲清表名列名映射、类型推断、单引号转义和批量导入,附一段真实输入输出例子。
CSV 转 SQL 实战:从表格生成 INSERT 语句批量导入数据库
手头有一份 CSV,要把它灌进数据库,这是开发里几乎每周都会撞到的活。表格可能来自运营导出的 Google Sheets,可能是同事邮件发来的注册名单,也可能是从老库 dump 出来准备搬家的数据。要让这些数据进库,本质上就是把每一行变成一条 INSERT 语句,再配一份能装下它们的表结构。
听起来简单,真动手会发现坑不少:列名里有空格、值里夹着单引号、空单元格到底算 NULL 还是空字符串、邮编 02134 被当成数字丢了前导零。下面把这条路从头到尾走一遍。
INSERT INTO 语法到底长什么样
一条标准的插入语句结构很固定:
INSERT INTO products (id, name, price, in_stock) VALUES
(1, 'Keyboard', 199.00, 1),
(2, 'O''Brien Mug', 39.50, 0);
三个要点。第一,列名列表写在表名后的括号里,顺序要和 VALUES 里的值一一对应。第二,字符串值用单引号包,数字和布尔不包。第三,值里如果有单引号,要写成两个单引号转义,所以 O'Brien 变成 'O''Brien',否则引号会提前闭合,整条语句报语法错误。
批量插入就是把多组 VALUES 用逗号串起来,放在一条语句里。这种写法导入最快,数据库只解析一次。
表名和列名怎么映射
CSV 的第一行是表头,它直接决定列名。如果导出的文件没有表头,先补一行名字,不然生成出来的列名会是 col_1、col_2 这种,后面写查询时根本认不出哪列是哪列。
列名还要清洗成合法标识符。表头里的「Order Date」带空格,不能直接当列名,空格要转成下划线变成 order_date。碰上 SQL 保留字(比如 order、select),就得加引号包起来。表名则由你自己指定,比如 products、users。
标识符的引用方式还分方言。MySQL 用反引号:` order_date ;PostgreSQL 和 SQLite 用双引号:"order_date"。布尔列在 PostgreSQL 输出 TRUE/FALSE,在 MySQL 和 SQLite 输出 1/0`。换库的时候这些差异最容易被忽略,手动改起来很烦,交给工具按方言切换更稳。
类型推断:别让一个杂值毁掉整批导入
CREATE TABLE 要给每列定类型。靠谱的做法是扫一整列的所有行再下结论:全是整数就是 INT,带小数就是 DECIMAL,全是 true/false/1/0 就是 BOOLEAN,匹配 YYYY-MM-DD 就是 DATE,其余落到 VARCHAR,长度按最长值取上一个合适的容量。
关键规则是:只要列里出现一个不符合的值,就整列回退到 VARCHAR。这样某一行的杂值不会让推断出的类型装不下数据,导致 INSERT 中途失败。
但推断不是万能的。一列美国邮编 02134 全是数字,会被推成 INT,前导零直接没了。所以生产环境的表结构,务必回看一眼 CREATE TABLE,把编码、ID、电话这类前导零或格式重要的列手动改成 VARCHAR。
一段真实的输入输出
输入这样一段 CSV:
id,name,price,in_stock
1,Keyboard,199.00,true
2,O'Brien Mug,39.50,false
选 PostgreSQL 方言、表名 products,生成的结果是:
CREATE TABLE "products" (
"id" INT,
"name" VARCHAR(16),
"price" DECIMAL(10,2),
"in_stock" BOOLEAN
);
INSERT INTO "products" ("id", "name", "price", "in_stock") VALUES
(1, 'Keyboard', 199.00, TRUE),
(2, 'O''Brien Mug', 39.50, FALSE);
注意三处自动处理:price 被推成 DECIMAL,in_stock 推成 BOOLEAN 并输出大写 TRUE/FALSE,第二行那个撇号被转义成了两个单引号。复制下来直接 psql mydb < products.sql 就能跑。
批量 INSERT 还是逐行 INSERT
两种模式各有用处。批量模式把所有行塞进一条 VALUES,导入最快,适合几千几万行的真实数据灌库。逐行模式每个数据行一条语句,版本控制里 diff 更干净,改某一行 fixture 时一眼能看出动了哪条,审查者还能注释掉单独一行隔离不稳定的用例。做种子数据、测试 fixture 选逐行,跑真实批量导入选批量。
我自己的用法
我常干的一件事是从开发库快速搭测试数据。把一份产品目录从表格导出成 CSV,粘进 CSV 转 SQL 转换器,方言选 PostgreSQL,表名设 products,一次粘贴就拿到带类型的建表语句加批量 INSERT,省掉手写表结构再手敲几十行的功夫。如果只是想先看看 CSV 解析对不对、不急着进库,我会先用 CSV 转 JSON 工具 把结构摊开核对一遍,确认没有错位再生成 SQL。整个过程都在浏览器本地跑,数据不出标签页,处理客户数据时也踏实。
把握住列名映射、类型推断和单引号转义这三件事,CSV 进库就不再是手敲的体力活,而是粘贴、复制、执行三步的事。
Made by Toolora · Updated 2026-06-13