CSV 转 SQL

从 CSV 数据生成 SQL INSERT 语句

加载示例

CSV 输入

SQL 输出

本地运行 · 粘贴密钥安全无忧
SQL 将显示在此处…
表名:

什么是 CSV 转 SQL 转换?

CSV 转 SQL 转换将逗号分隔值转换为关系型数据库可执行的结构化查询语言语句。最常见的输出形式是一对语句:一条定义列的 CREATE TABLE 语句,以及一条或多条将 CSV 文件各行数据填入相应列的 INSERT INTO 语句。

CSV 文件遵循 RFC 4180 规范:每行为一条记录,字段由分隔符(通常为逗号)分隔,包含分隔符或换行符的字段用双引号括起。SQL 则是管理 PostgreSQL、MySQL、SQLite 和 SQL Server 等系统中数据的标准语言。在这两种格式之间进行转换,是软件开发中最常见的数据导入任务之一。

一个合格的 CSV 转 SQL 转换器需要处理引用规则、对值中的单引号进行转义(按 SQL 标准将其加倍为 '')、将列标题映射为合法的 SQL 标识符,并可选择性地推断数据类型。除基本转义外,优质转换器还会规范化列名(将空格和连字符替换为下划线),并将输出包裹在事务块中——这样导入失败时可以干净回滚,而不会在表中留下不完整的数据。若不借助转换器,即便只有几百行数据,手工编写 INSERT 语句也既容易出错又效率低下。

为什么使用 CSV 转 SQL 转换器?

从电子表格数据手工编写 SQL INSERT 语句既繁琐又容易引入语法错误。转换器可自动完成重复性工作,让你专注于数据库结构设计和数据验证。

秒级生成 SQL
粘贴 CSV 即可获得可直接运行的 SQL 输出,无需手动为字符串加引号、转义单引号或逐一核对列数。转换完全在浏览器中执行。
🔒
数据留在浏览器中
你的 CSV 数据不会离开本机。所有解析和 SQL 生成均在客户端完成,无需上传至服务器,不产生日志,也不存在第三方访问数据集的风险。
🎯
生成正确的 SQL 语法
值中的单引号按 SQL 标准转义为 '',列名经过规范化处理以生成合法标识符。输出对 PostgreSQL、MySQL 和 SQLite 均语法正确。
📋
兼容任意 CSV 结构
工具自动检测分隔符(逗号、分号、制表符、竖线),并按 RFC 4180 规则处理包含嵌入逗号或换行符的引用字段。

CSV 转 SQL 使用场景

数据库初始化填充
将 CSV 数据文件转换为 INSERT 语句,用于开发或预发布数据库的初始化。在需要可重复种子数据且不使用 ORM 的 CI 流水线中尤为实用。
数据迁移
将从某一系统(CRM、电子表格、旧版应用)导出的数据迁移到新的关系型数据库。生成 SQL、审查无误后,在事务中执行。
后端 API 开发
快速将 CSV 测试数据填充到本地 PostgreSQL 或 MySQL 实例中。当只需一次性加载时,比编写迁移脚本更高效。
QA 与测试自动化
从 CSV 测试数据生成 SQL,在集成测试前建立数据库初始状态。配合清理脚本,可在每轮测试之间重置表数据。
数据分析准备
将 CSV 数据集加载到 SQLite 中进行即席查询。SQLite 可直接读取 SQL INSERT 语句,是从电子表格导出到可查询数据的快捷路径。
学习 SQL
学生可以将示例 CSV 转换为 SQL,在真实数据上练习 SELECT、JOIN 和聚合查询,无需从头设计数据库结构。

SQL 数据类型参考

将 CSV 转换为 SQL 时,由于 CSV 不携带类型元数据,所有列默认使用 TEXT 类型。如果你已知列的类型,可以在 CREATE TABLE 输出中替换 TEXT。下表列出最常用的 SQL 类型及其适用场景。

类型适用场景说明
TEXT / VARCHARStrings, mixed contentDefault safe choice; works in every SQL dialect
INTEGER / INTWhole numbers (age, count, ID)Use when column contains only digits with no decimals
REAL / FLOATDecimal numbers (price, rate)Needed for columns with dots like 19.99 or 3.14
DATEISO 8601 dates (2024-01-15)Requires consistent formatting; varies by database
BOOLEANtrue/false, 1/0, yes/noMySQL uses TINYINT(1); PostgreSQL has native BOOL
NUMERIC / DECIMALExact precision (currency)Specify scale: DECIMAL(10,2) for money columns
BLOB / BYTEABinary dataRarely needed in CSV imports; use for hex-encoded fields

SQL 方言对比

不同数据库引擎的 SQL 语法存在差异。生成的 INSERT 语句使用标准 SQL,在大多数系统中均可运行,但某些特性有所不同。下表总结了导入 CSV 数据时最需关注的差异点。

特性PostgreSQLMySQLSQLiteSQL Server
Identifier quoting"col"`col`"col"[col]
String escape'''' or \'''''
INSERT syntaxINSERT INTOINSERT INTOINSERT INTOINSERT INTO
Batch INSERTVALUES (),()…VALUES (),()…VALUES (),()…max 1000 rows
Auto-incrementSERIALAUTO_INCREMENTAUTOINCREMENTIDENTITY(1,1)
Upsert / mergeON CONFLICTON DUPLICATE KEYON CONFLICTMERGE
NULL handlingIS NULLIS NULL / <=>IS NULLIS NULL
COPY from CSVCOPY … FROMLOAD DATA INFILE.importBULK INSERT

INSERT 与 COPY:如何选择导入方式

对于小到中等规模的数据集(不超过 10,000 行),INSERT 语句效果良好,且可跨所有 SQL 数据库移植。对于大规模导入,数据库提供完全绕过 SQL 解析器的批量加载命令。

INSERT INTO
标准 SQL,适用于所有数据库。每行数据作为一条 SQL 语句解析,因此在大数据集上开销较高。支持条件逻辑(ON CONFLICT、ON DUPLICATE KEY)。最适合种子数据、小规模迁移,以及需要逐行控制的场景。
COPY / LOAD DATA
数据库专有的批量加载工具。PostgreSQL 使用 COPY,MySQL 使用 LOAD DATA INFILE,SQLite 使用 .import,SQL Server 使用 BULK INSERT。直接读取 CSV,跳过 SQL 解析器,对大文件(10 万行以上)速度提升 10 至 100 倍。需要在服务器或客户端具备文件系统访问权限。

代码示例

以下示例展示如何在不同编程语言中将 CSV 转换为 SQL INSERT 语句,每个示例均处理单引号转义和列名规范化。

JavaScript (Node.js)
// CSV → SQL INSERT statements
const csv = `name,age,city
Alice,30,Berlin
Bob,25,Tokyo`

function csvToSql(csv, table = 'data') {
  const rows = csv.trim().split('\n').map(r => r.split(','))
  const [headers, ...data] = rows
  const cols = headers.map(h => h.trim().toLowerCase().replace(/\s+/g, '_'))

  const values = data.map(row =>
    '  (' + row.map(v => `'${v.replace(/'/g, "''").trim()}'`).join(', ') + ')'
  )

  return `INSERT INTO ${table} (${cols.join(', ')}) VALUES
${values.join(',\n')};`
}

console.log(csvToSql(csv, 'users'))
// → INSERT INTO users (name, age, city) VALUES
//     ('Alice', '30', 'Berlin'),
//     ('Bob', '25', 'Tokyo');
Python
import csv
import io

csv_string = """name,age,city
Alice,30,Berlin
Bob,25,Tokyo"""

reader = csv.reader(io.StringIO(csv_string))
headers = [h.strip().lower().replace(' ', '_') for h in next(reader)]

table = 'users'
rows = list(reader)

# CREATE TABLE
col_defs = ', '.join(f'{h} TEXT' for h in headers)
print(f'CREATE TABLE {table} ({col_defs});')
# → CREATE TABLE users (name TEXT, age TEXT, city TEXT);

# INSERT statements
for row in rows:
    vals = ', '.join(f"'{v.replace(chr(39), chr(39)*2)}'" for v in row)
    print(f"INSERT INTO {table} ({', '.join(headers)}) VALUES ({vals});")
# → INSERT INTO users (name, age, city) VALUES ('Alice', '30', 'Berlin');
# → INSERT INTO users (name, age, city) VALUES ('Bob', '25', 'Tokyo');
Go
package main

import (
	"encoding/csv"
	"fmt"
	"strings"
)

func csvToSQL(data, table string) string {
	r := csv.NewReader(strings.NewReader(data))
	records, _ := r.ReadAll()
	if len(records) < 2 {
		return ""
	}

	headers := records[0]
	var vals []string
	for _, row := range records[1:] {
		escaped := make([]string, len(row))
		for i, v := range row {
			escaped[i] = "'" + strings.ReplaceAll(v, "'", "''") + "'"
		}
		vals = append(vals, "  ("+strings.Join(escaped, ", ")+")")
	}

	return fmt.Sprintf("INSERT INTO %s (%s) VALUES\n%s;",
		table, strings.Join(headers, ", "), strings.Join(vals, ",\n"))
}

func main() {
	csv := "name,age,city\nAlice,30,Berlin\nBob,25,Tokyo"
	fmt.Println(csvToSQL(csv, "users"))
	// → INSERT INTO users (name, age, city) VALUES
	//     ('Alice', '30', 'Berlin'),
	//     ('Bob', '25', 'Tokyo');
}
CLI (sqlite3 / psql)
# SQLite: import CSV directly into a table
sqlite3 mydb.db <<EOF
.mode csv
.import data.csv users
SELECT * FROM users LIMIT 5;
EOF

# PostgreSQL: COPY from CSV file (server-side)
psql -c "COPY users FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true);"

# PostgreSQL: \copy from CSV (client-side, no superuser needed)
psql -c "\copy users FROM 'data.csv' WITH (FORMAT csv, HEADER true);"

# MySQL: LOAD DATA from CSV
mysql -e "LOAD DATA INFILE '/path/to/data.csv' INTO TABLE users
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\n' IGNORE 1 ROWS;"

常见问题

CSV 值中的单引号在 SQL 输出中如何处理?
CSV 值中的每个单引号(')在 SQL 输出中都会加倍为 '',这是 SQL 标准的转义方式。例如,值 "O'Brien" 在 INSERT 语句中会变为 'O''Brien'。此方式适用于 PostgreSQL、MySQL、SQLite 和 SQL Server。
能否将 CSV 转换为特定数据库(如 MySQL 或 PostgreSQL)的 SQL?
生成的 INSERT 语句使用 MySQL 和 PostgreSQL 均支持的标准 SQL 语法。主要区别在于标识符的引用方式:PostgreSQL 使用双引号,MySQL 使用反引号。对于基本的 INSERT 操作,输出无需修改即可在两种数据库中使用。
如果 CSV 没有表头行会怎样?
转换器将第一行视为列标题。如果 CSV 没有表头,请在转换前添加一行表头,否则第一行数据会成为 CREATE TABLE 语句中的列名。本工具(和大多数转换器一样)要求必须有表头行。
CSV 转 SQL 有行数限制吗?
由于转换在浏览器中运行,实际上限取决于设备内存。数万行的文件通常不会有问题。对于超大文件(50 万行以上),建议改用数据库原生的 COPY 或 LOAD DATA 命令,而非 INSERT 语句。
为什么输出对所有列都使用 TEXT 类型,而不是 INTEGER 或 DATE?
CSV 是纯文本格式,不携带类型元数据。转换器使用 TEXT 作为安全默认值,以避免错误的类型推断。查看数据后,你可以在生成的 CREATE TABLE 语句中修改列类型——数值列改为 INTEGER,日期列改为 DATE,是最常见的调整。
如何处理以分号或制表符为分隔符的 CSV 文件?
本工具通过分析 CSV 第一行自动检测分隔符,检测范围包括逗号、分号、制表符和竖线,并使用出现频率最高的一种。使用分号的欧洲格式 CSV 无需任何配置即可正常处理。
直接运行生成的 SQL 是否安全,能否防止注入?
输出会对单引号进行转义,可防止意外的语法错误。但如果 CSV 数据来源不可信,应像对待任何未经验证的输入一样审查生成的 SQL,在对生产数据库执行之前务必仔细检查。对于程序化导入,参数化查询始终比字符串拼接更安全。