SQLInsert转JSON转换器

把 INSERT INTO 表 (列) VALUES (...),(...); 语句解析成 JSON:认得单引号状态的扫描器,字符串里的逗号、括号、井号都不拆值;'' 表示一个字面单引号,同时支持 MySQL 反斜杠转义;NULL、TRUE/FALSE 与数字自动推断类型,NOW() 等函数调用保留原文并标注未求值。本地解析不上传。

本次 3 个对象、18 个值、未求值函数 2 处。

默认示例是一条三组值的 INSERT:第一组含双引号与 NOW(),第二组含 '' 转义与 NULL,第三组含反斜杠 n 与 UUID()。输入框被清空时点「转为JSON」会自动填回示例;在「省略列名时的键前缀」里按回车也会重新转换。

使用方法

  1. 「SQL 源文本」默认已经写好一条三组值的 INSERT:第一组含双引号与 NOW(),第二组含两个连续单引号与 NULL,第三组含反斜杠 n 与 UUID()。
  2. 点「转为JSON」或在文本框里按 Ctrl+Enter(Mac 是 Cmd+Enter)完成转换;在「省略列名时的键前缀」输入框里按回车同样触发。
  3. 「省略列名时的键前缀」默认 col。遇到 INSERT INTO t VALUES (...) 这种没写列名的语句,键会取 col1、col2、col3;想换成 f1、c1 之类的前缀直接改这一栏。
  4. 「多条 INSERT 的输出方式」默认每条语句一个数组:粘贴三段 INSERT 会按顺序输出三个数组,彼此空一行;改成合并则所有语句的所有行摊进一个扁平数组。
  5. 「输出缩进空格数」默认 2,可填 0 到 8 的整数;填 0 输出压缩成一行,方便比较两份 seed 数据的差异,填 4 更贴近常见编辑器的保存宽度。
  6. 结果区第一行是统计摘要:语句条数、对象数、涉及的表、未求值函数清单与四类值的计数;下面是输出原文,「复制结果」复制的就是它。
  7. 输入框被清空时点「转为JSON」会自动填回示例;本页不联网,也不写 localStorage,刷新即恢复默认。
  8. 下方是二十行值形态对照表,默认显示 12 行,点「加载更多」看余下 8 行;「导出 CSV」存成带字节序标记的文件,「复制对照表」复制成制表符分隔文本。

这个SQLInsert转JSON转换器能解决什么

把数据库导出脚本里的 INSERT 语句搬进前端或测试工具时,最常见的做法是复制粘贴成对象字面量,手工做既慢又容易错。这个SQLInsert转JSON转换器做的是按 SQL 的词法规则把语句解析成结构化数据:有几组括号就输出几个对象,一整条语句输出一个数组,多组多列都能一次转完。

第一类场景是 seed 数据搬运。测试夹具、演示数据、题库常常以 INSERT 脚本形式存在,转成 JSON 后可以直接被前端 mock、Node 脚本或配置中心消费。字符串里的逗号、括号、单引号都会被正确处理,不会把一条记录切成两半。

第二类场景是数据体检。列数和值数不一致、字符串引号没闭合、混进了 SELECT 语句,这些在成千上万行导出脚本里很难肉眼发现。本页的每条报错都带「第几条语句、第几组、第几个值」的定位,并说明原因,不用人工数行。

边界也要说清:本页只解析 INSERT ... VALUES 这一种形态,不支持 INSERT ... SELECT、ON DUPLICATE KEY UPDATE、多表 INSERT 与存储过程;函数调用一律不求值,只保留原文。要执行 SQL 或做库级迁移,请使用数据库客户端。

扫描与类型推断原理

解析分四步。第一步剥离注释:扫描时维护「是否在单引号字符串内」,字符串外的 -- 到行尾与 /* */ 块注释被删掉,并用一个空格替代,避免把两侧的符号粘成一个 token;字符串里的 -- 与 /* */ 原样保留。第二步按分号切语句,同样只在字符串外切。第三步解析每条语句的 INSERT INTO 表名、可选列名与 VALUES 之后的若干组括号,组与组之间用逗号分隔。

第四步是核心:切分一组里的各个值。这里必须用认得引号状态的扫描器——按逗号切分会把 'a, b' 切成两半,按括号切分会把 'a)b' 截断。扫描器在字符串内时只认两种特殊形态:两个连续单引号(SQL 标准的字面单引号转义)与反斜杠转义,其余字符连同逗号、括号一起吞掉;在字符串外时才记录括号深度,只在深度 0 的逗号处断开。

类型推断按值的形态决定:匹配数字正则(含负数、小数、科学计数法)的转 number;NULL 转 null;TRUE 与 FALSE 转布尔,三者都不区分大小写;以单引号开头的是字符串,其中的 \n、\t、\\、\' 被还原,'' 还原成一个单引号;形如标识符加左括号的(NOW()、UUID())判定为函数调用,保留原文字符串并在摘要里列出,不假装算出一个值;其余裸词按字符串原样保留。

表名支持三种包裹符:反引号(MySQL)、方括号(SQL Server)、双引号(PostgreSQL),解析时剥掉外壳只留名字。列名同样剥掉外壳。输出 JSON 时不带字节序标记。

变量含义取值影响
pre省略列名时的键前缀合法标识符键名为前缀加序号,从 1 起
multi多语句输出方式split / mergesplit 按语句分开,merge 摊平
ind输出缩进空格数0 ~ 8 的整数0 表示压缩成一行
iq单引号状态true 表示处于字符串内为 true 时逗号与括号不当分隔符
depth括号深度非负整数只在深度 0 处按逗号拆值

完整示例

默认源文本是一条三组值的 INSERT。逐组看:第一组的 bio 里有一对双引号,它在单引号字符串内,是普通字符;created 是 NOW(),保留原文。第二组的 bio 写了两个连续单引号,还原成一个单引号,得到 "It's fine";score 是 NULL,转成 null。第三组的 bio 里是反斜杠 n,还原成真换行;created 是 UUID(),同样保留原文。

-- 用户表批量插入                                    → 行注释,整段剥离
INSERT INTO `users` (id, name, bio, score, active, created) VALUES
  (1, 'Alice', 'She said "hi"', 95.5, TRUE, NOW()),       → 第 1 组,6 个值
  (2, 'Bob', 'It''s fine', NULL, FALSE, '2024-01-02 …'),  → 第 2 组,'' 是字面单引号
  (3, 'Carol', 'line1\nline2', 0, NULL, UUID());          → 第 3 组,反斜杠 n 是真换行

输出是一个含三个对象的数组,对象键就是列名 id、name、bio、score、active、created。把「多条 INSERT 的输出方式」改成合并,再粘贴第二条 INSERT,两个语句的六行会摊进同一个数组;保持分开则输出两个数组,彼此空一行。把「省略列名时的键前缀」改成 f,第三行那种没写列名的语句就会得到 f1、f2 这样的键。

值形态对照表

下表列出二十种 SQL 写法经过本页解析后的结果,由页面自己的解析器逐条算出,前十二行直接展开,点工具区的「加载更多」看余下八行。报错行给出的是完整错误文案。

源语句解析结果说明
INSERT INTO t (a) VALUES (1);[{"a":1}]一组一值
INSERT INTO t (a,b) VALUES (1,'x'),(2,'y');[{"a":1,"b":"x"},{"a":2,"b":"y"}]两组两对象
INSERT INTO t VALUES (1,'x');[{"col1":1,"col2":"x"}]省略列名
INSERT INTO t (a) VALUES ('It''s ok');[{"a":"It's ok"}]''=字面单引号
INSERT INTO t (a) VALUES ('x\ny');[{"a":"x\ny"}]反斜杠n
INSERT INTO t (a) VALUES ('a, b');[{"a":"a, b"}]串内逗号不拆
INSERT INTO t (a) VALUES ('a)b');[{"a":"a)b"}]串内右括号
INSERT INTO t (a) VALUES (NOW());[{"a":"NOW()"}]函数保原文
INSERT INTO t (a,b) VALUES (NULL,TRUE);[{"a":null,"b":true}]NULL/TRUE
INSERT INTO t (a) VALUES (FALSE);[{"a":false}]FALSE布尔
INSERT INTO t (a) VALUES (-3.5);[{"a":-3.5}]负数
INSERT INTO t (a) VALUES (1e3);[{"a":1000}]科学计数法
INSERT INTO `tbl` (a) VALUES (1);[{"a":1}]反引号表名
INSERT INTO [tbl] (a) VALUES (1);[{"a":1}]方括号表名
INSERT INTO "tbl" (a) VALUES (1);[{"a":1}]双引号表名
INSERT INTO t (a) VALUES (1); -- 行尾注释[{"a":1}]行注释剥离
/* 前注释 */ INSERT INTO t (a) VALUES (1);[{"a":1}]块注释剥离
INSERT INTO t (a) VALUES ('a--b');[{"a":"a--b"}]串内双横线非注释
INSERT INTO t (a,b) VALUES (1);报错:第 1 条语句第 1 组有 1 个值,与 2 个列名不符。列值数不符
SELECT * FROM t;报错:第 1 条语句不是 INSERT INTO 开头非 INSERT

第二张表汇总类型推断规则。大小写不敏感:null、Null、NULL 等价,true 与 TRUE 等价。

值写法推断类型说明
1 / -3.5 / 1e3number匹配数字正则才转,其余按字符串
'x'string'' 与反斜杠转义在字符串内还原
NULLnull大小写不敏感
TRUE / FALSEboolean大小写不敏感
NOW() / UUID()string(保留原文)摘要标注未求值,不计算结果
DEFAULT 等裸词string不在上表之内的原样保留

结果边界与错误提示

常见问题

为什么不直接按逗号切分?

因为逗号可能出现在字符串里。VALUES ('a, b', 2) 按逗号切会把一个字符串切成两半,后面的值全部错位。SQL 的词法规定字符串以单引号界定,只有维护「是否在单引号内」的状态才能正确找到分隔逗号,这也是本页扫描器的核心。

'' 和 \' 哪个才对?

SQL 标准用两个连续单引号表示一个字面单引号,写 'It''s ok' 得到 It's ok。反斜杠转义不是标准做法,但 MySQL 默认支持,本页两种都认:\' 变单引号,\\ 变一个反斜杠,\n 与 \t 变真换行与制表符。

NOW() 为什么不求值?

因为求值需要数据库环境,浏览器里没有当前时间戳与会话上下文,硬算出来的值必然和真实库不一致。本页保留原文并在摘要里列出未求值函数,把「这里原本是个函数」明确暴露出来,由你决定是否在数据库端补上默认值。

列名省略时键叫什么?

默认取 col1、col2、col3,序号从 1 开始,可以在「省略列名时的键前缀」里改。列名省略的 INSERT 依赖表中列的实际顺序,换环境极易错位,转完后务必对照表结构确认一遍。

多条 INSERT 为什么默认分开输出?

因为不同语句可能写不同表、不同列,合并会让来源不可考。默认每条语句输出一个数组,摘要里列出涉及的所有表;需要摊平时可切到合并模式,所有行进入同一个数组,键不一致的对象也能共存。

字符串里的括号、逗号、井号会出问题吗?

都不会。逗号在字符串内不是分隔符,右括号在字符串内不会提前结束值组,井号在 SQL 里没有特殊含义。扫描器只在字符串外才处理这些符号,注释剥离也同样只在字符串外生效。

支持 INSERT ... SELECT 吗?

不支持。本页只解析 INSERT INTO 表 (列) VALUES (...), (...); 这一种形态,读到 VALUES 之外的结构会提示不支持。INSERT ... SELECT 的源是查询结果,要转 JSON 应先把查询结果导出成值列表。

导出的文件带 BOM 吗?

JSON 输出与复制都不带字节序标记,避免下游解析器把 BOM 当成语法错误;只有值形态对照表的 CSV 导出带 BOM,这是给 Excel 开门用的。两者取向刻意相反。

相关工具