ToolAct工具行动

CSV 转 SQL 工具

将 CSV 数据转换为 SQL INSERT 语句,支持多种数据库格式

拖放 CSV 文件到此处,或点击选择文件

什么是 CSV 转 SQL?

CSV 转 SQL 工具将逗号分隔值格式的表格数据转换为 SQL INSERT 语句,可直接在数据库中执行。支持生成完整的建表语句和数据插入语句,适用于数据迁移、批量导入、数据库初始化等场景。省去手工编写 SQL 的繁琐工作,特别适合大量数据的批量处理。CSV 转 SQL 会把表格数据生成 INSERT 等 SQL 语句,但能否安全导入取决于字段类型、转义、null 处理和目标数据库方言。列名应提前检查,保留字需要避免或正确引用。用于生产数据导入时,事务、备份、字符编码和在副本库中试跑,比单纯生成 SQL 文本更重要。

使用方法

使用方法

  1. 在输入框中粘贴或输入 CSV 数据,或上传 CSV 文件
  2. 设置表名(默认为 table_name)
  3. 选择适当的分隔符(默认为逗号)
  4. 选择是否将第一行作为字段名
  5. 右侧将生成 SQL INSERT 语句

导入安全提示

  • 执行前请检查生成的 INSERT 语句中的表名、列顺序、转义、NULL 值和数字格式。
  • 先进行小批量测试,如果数据库支持,请将正式导入放在事务中执行。

使用场景

从小型 CSV 导出生成 INSERT 语句上传 CSV、TSV 或文本表格,选择分隔符,设置表名,使用表头名称或生成的 col1、col2、col3 列名生成 SQL INSERT 语句。解析和语句生成均在浏览器中运行,导入的行在粘贴到 psql、mysql 或迁移工具之前不会离开设备。
匹配数据库风格的标识符引号在 MySQL 的反引号、PostgreSQL/标准 SQL 的双引号和字符串字面量的单引号之间切换,可选生成包含 VARCHAR(255) 列的简单 CREATE TABLE 语句。作为受控的中间步骤使用,然后在依赖之前验证 SQL 是否兼容目标数据库版本。
准备种子数据并关注 SQL 限制工具会转义值中的单引号和双引号,支持四种分隔符,适合演示、本地测试数据和管理修复草稿,但不会推断数据类型、约束、索引、事务或数据库特有的批量加载语法(如 COPY、LOAD DATA 或多行 VALUES 批处理)。
向共享数据库播种时添加 IF NOT EXISTS 保护将生成的 INSERT 批次包裹在 BEGIN/COMMIT 事务中,或搭配手动的 DELETE/INSERT 模式,避免在开发和预发布环境中重复运行种子数据时产生重复行。由于所有解析在本地完成,可以在不重新上传客户或预发布数据到外部服务的情况下反复迭代种子数据。
当实际列需要 TEXT 或 DECIMAL 时调整 VARCHAR(255)CREATE TABLE 草稿对每列都使用 VARCHAR(255),因此在生产环境运行插入之前,需要在迁移中将长描述改为 TEXT、货币值改为 DECIMAL(p,s)、时间戳改为 TIMESTAMP。对照实际 schema 审核生成的列类型,而非照搬草稿。类型推断是纯词法的:只有当样本行已经证明时才会如此处理,空单元格按 SQL 三值逻辑变为 NULL 而非空字符串,表名清理会去除空格和标点但不会为 MySQL 的保留关键字加引号。大多数引擎还建议每批大约 1000 行的多行 VALUES 批处理以保持在数据包大小限制内。

技术原理

CSV 输入通过符合 RFC 4180 的状态机解析(处理带引号字段、转义的双引号和 CRLF/LF 换行符),然后输出为 ANSI SQL INSERT 语句。两种语法互不重叠:CSV 使用双引号加倍进行转义("O""Brien"),而 SQL 按 ISO/IEC 9075 在字符串字面量内使用单引号加倍('O''Brien')。转换器在用单引号包裹值之前,将每个内部单引号改写为一对单引号,这是在 MySQL、PostgreSQL、SQLite、SQL Server 和 Oracle 之间唯一保证有效的转义机制。标识符引号因方言而异:MySQL 使用反引号 `users`,PostgreSQL 和 SQL Server 使用双引号 "users"(加引号时区分大小写),SQLite 两种都接受 — 选择与目标引擎匹配的风格以避免因大小写折叠导致的「未知列」错误。 类型推断有意保持最低限度,因为 CSV 没有类型元数据。可选的 CREATE TABLE 草稿对每列都输出 VARCHAR(255) — 安全但并非最优 — 留给用户在运行前替换为 INT、BIGINT、DECIMAL(p,s)、DATE、TIMESTAMP 或 TEXT。空单元格输出为 NULL(SQL 三值逻辑中的缺失标记)而非空字符串 '',因为大多数电子表格导出使用空白字段表示缺失数据;如果空字符串的区别很重要,请改用类型化加载器。保留字如 user、order 和 group 不会自动加引号,因此一个名为 order 的列在 MySQL 上会解析失败,除非用户手动用反引号包裹。 对于大型导入,单行 INSERT 语句正确但速度慢:MySQL 默认的 max_allowed_packet 为 64 MB,每批约 1000 行的多行 INSERT INTO t VALUES (...), (...), (...) 通常比每行一条语句快 5-10 倍,因为网络往返和解析开销更少。将批次包裹在 BEGIN; ... COMMIT; 中可以让数据库暂存插入并原子提交,当部分插入会导致外键关系不一致时这至关重要。注意本工具不会推断外键、索引、主键约束或 AUTO_INCREMENT — 它只转换行数据,因此接收表结构必须已存在,或者 CREATE TABLE 草稿必须在执行前编辑。对于数百万行的批量加载,优先使用数据库原生语法:PostgreSQL COPY FROM、MySQL LOAD DATA INFILE 或 SQL Server bcp。

  • SQL 字符串字面量转义遵循 ISO/IEC 9075:单引号加倍('O''Brien'),而非反斜杠转义。
  • 标识符引号不同:MySQL 用反引号,PostgreSQL/SQL Server 用双引号,SQLite 两种都接受。
  • 空 CSV 单元格 -> SQL NULL(三值逻辑),而非 '' — 空字符串的区别会丢失。
  • 保留字(order、user、group)不会自动加引号;需要手动转义。
  • 每批约 1000 行的多行 INSERT 吞吐量约为单行语句的 5-10 倍(MySQL max_allowed_packet 默认 64 MB)。
  • 用 BEGIN; ... COMMIT; 包裹以实现原子种子插入;部分失败可干净回滚。
  • 超过 100 万行的批量加载:优先使用 PostgreSQL COPY、MySQL LOAD DATA INFILE、SQL Server bcp 而非生成的 INSERT。

示例

基础 CSV → INSERT 语句(MySQL 反引号风格)

CSV:
id,name,email
1,Alice,alice@example.com
2,Bob,bob@example.com

SQL:
INSERT INTO `users` (`id`, `name`, `email`) VALUES (1, 'Alice', 'alice@example.com');
INSERT INTO `users` (`id`, `name`, `email`) VALUES (2, 'Bob',   'bob@example.com');

包含 CREATE TABLE(PostgreSQL 双引号风格)

CSV:
product_id,price,in_stock
101,29.99,true
102,15.50,false

SQL:
CREATE TABLE "products" (
  "product_id" VARCHAR(255),
  "price"      VARCHAR(255),
  "in_stock"   VARCHAR(255)
);
INSERT INTO "products" ("product_id", "price", "in_stock") VALUES ('101', '29.99', 'true');
INSERT INTO "products" ("product_id", "price", "in_stock") VALUES ('102', '15.50', 'false');
-- 提示: 上线前请把 VARCHAR(255) 改为合适的类型,比如 INT / DECIMAL(10,2) / BOOLEAN。

转义值中的单引号

CSV:
id,note
1,O'Brien signed off
2,It's already done

SQL:
INSERT INTO `notes` (`id`, `note`) VALUES (1, 'O''Brien signed off');
INSERT INTO `notes` (`id`, `note`) VALUES (2, 'It''s already done');
注意: 单引号用两个单引号('')转义,这是 SQL 标准写法。

类型推断——INT、DECIMAL、TEXT 的判定

CSV:
user_id,score,bio
1,100,Hello
2,87.5,Long bio text...

推断结果(启发式):
  user_id -> INT
  score   -> DECIMAL(10,2)
  bio     -> VARCHAR(255)  (内容较长时建议改用 TEXT)

SQL 预览:
INSERT INTO `students` (`user_id`, `score`, `bio`) VALUES (1, 100, 'Hello');
INSERT INTO `students` (`user_id`, `score`, `bio`) VALUES (2, 87.5, 'Long bio text...');

常见问题

工具生成的是哪种 SQL?

生成标准的 CREATE TABLE 加 INSERT INTO 语句。默认使用通用 SQL 方言——稍作类型调整后即可在 MySQL、PostgreSQL、SQLite、MSSQL 上运行。部分页面允许你针对数据类型选择具体方言(VARCHAR vs TEXT、INT vs INTEGER 等)。

列名是怎么得来的?

在启用「首行为表头」时取自 CSV 第一行。页面会对名称做规范化处理:将空格替换为下划线,并对保留字加引号。如果未启用表头,则列名依次为 col_1、col_2 等。

每列的数据类型是怎么推断的?

页面会对值采样后选择能容纳所有值的最窄类型:所有单元格都是整数则用 INTEGER,存在小数则用 DECIMAL,VARCHAR(N) 的长度按最长单元格设置,true/false 用 BOOLEAN,ISO 格式字符串用 DATE/DATETIME。在生成 SQL 之前你可以手动覆盖推断结果。

数据中的引号和特殊字符如何处理?

字符串值中的单引号会被转义为两个单引号(O'Brien → 'O''Brien')。反斜杠和 Unicode 字符按字面值原样输出——这与 PostgreSQL 在 standard_conforming_strings = on 时的行为一致。如果目标是 MySQL,请在 NO_BACKSLASH_ESCAPES 模式下核对结果。

为什么 NULL 和空字符串不一样?

CSV 中真正空的单元格(如 'a,,c')会变成 SQL 的 NULL;带引号的空字符串('a,"",c')则变成 ''。页面遵循这一约定。如果你希望两种情况都保留为空字符串,请关闭「将空值视为 NULL」。

我的数据会被上传吗?

不会。CSV 解析和 SQL 生成都在你的浏览器中完成,输入和输出都不会离开页面。生成的结果会作为 SQL 脚本,由你自己导入到数据库服务器。

可以直接把生成的 SQL 用在生产数据库上吗?

建议先审查一遍。生成的 CREATE TABLE 不一定与你现有的 schema 匹配;INSERT 语句也不会包含约束、外键和索引。把它当作一个起点来编辑,特别是在主键、NOT NULL 约束和合适的数据类型上。