首页 › 编程开发 › SQL美化压缩
🔧

SQL美化压缩

自写词法分析器排版 SQL:子句换行、JOIN 与 CASE 分层缩进、IN 超阈值自动折行,压成单行时把行注释改写成块注释,字符串里的分号与括号不误伤

格式化选项
缩进 关键词 IN 折行阈值
美化保留全部注释并留在原来的位置;压成单行时行注释会改写成块注释,免得把后面的语句吃掉。
美化结果
词法说明
格式化只重排空白,不会改动字符串、注释、标识符里的内容:单引号与双引号字符串(含 '' 翻倍转义、反斜杠转义、 E'…' / N'…' / X'…' / U&'…' 前缀、跨行字符串)、反引号 `带 空格`、方括号 [标识符]、-- 与 # 行注释、/* */ 块注释、@@变量、:命名参数、? 占位符,以及 <> != >= || :: ->> ?. 这类多字运算符都能正确切分。
两处按主流方言习惯取默认:反斜杠在引号字符串里一律当转义符(MySQL 默认行为);双引号内容按字符串着色,但整段原样输出, 所以 ANSI 的双引号标识符同样不会被改坏;# 优先识别为 MySQL 行注释。括号不配对、引号或块注释没闭合时会给出大概位置并停止输出, 不会给出改坏一半的 SQL。

工具介绍

排版 SQL 的难点不在「加换行」,而在先弄清哪些字符属于代码、哪些属于内容。用正则找关键词再插换行的做法,碰上 WHERE remark LIKE '%; SELECT 1' 这种字符串,或者 -- 注释里也写了 FROM,就会把本来能跑的语句改坏。这个工具先做完整的词法切分,再只对代码与代码之间的空白动手,字符串、注释、标识符里的内容一个字符都不改。

三种模式各管一件事

  • 美化:子句换行加层级缩进,适合读长报表 SQL、写进设计文档、贴到工单里给人看
  • 压缩:一条语句收成一行,适合塞进日志、写进配置文件和定时任务参数,或者做 diff 之前先把两边统一成同一形态;行注释会改写成块注释,免得把后半句吃掉,也可以直接删掉
  • 只规范空白:保留你原来的行结构,只规整行内多余空格和运算符两侧空格,改动最小,已经排好版的项目用它

美化模式的排版规则

  • 顶层子句各占一行:SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY、LIMIT、INSERT、UPDATE、SET、VALUES、WITH 等,多词子句按整体识别,不会出现 GROUP 和 BY 被拆到两行
  • AND、OR、XOR 逐条换行:条件多的时候一屏能上下对齐比较,找漏写的那个括号条件很快
  • JOIN 家族分层:INNER、LEFT、RIGHT、FULL、CROSS、NATURAL 各起一行,ON 与 USING 的关联条件缩进到下一层,多表连接不再是横着一条长线
  • CASE 逐行展开:WHEN、ELSE、END 各占一行,且 END 不会把后面的 SELECT 列表吃掉——这是很多在线格式化器排版 CASE 时最常出的错
  • IN 列表按阈值折行:元素数超过阈值(默认 6)时一行一个,没超过就保持原样;函数调用的括号、OVER (...) 窗口定义、VALUES 元组不会被拆散
  • 子查询与括号各加一层:CTE、EXISTS、派生表的层级关系从缩进上直接读得出来
  • 语句之间空行分隔,统计行同时给出语句数、结果行数、最大缩进层级和输入字符数

词法层面不会碰的东西

  • 字符串:单引号与双引号、连写两个单引号表示一个引号的转义写法、反斜杠转义、跨行字符串,以及 E''、N''、X''、B''、U&'' 这些带前缀的形式,内容整段原样输出
  • 标识符:反引号 `带 空格`、方括号 [名称]、双引号标识符和中文列名都当一个整体,不会被切成关键字加残片
  • 注释:--、# 行注释与块注释留在原来的位置,行注释自带换行,不会被并进代码行
  • 参数与占位符:@@变量、:命名参数、? 位置占位不会被当成运算符处理
  • 多字运算符:>= <> != || :: ->> ?. 保持为一个符号,不会被拆成两个而改变语义
  • 数字:科学计数法、小数点起头、十六进制字面量各自归为一个完整 token

选项含义速查

选项可选值作用与差别
缩进2 / 4 / 8 空格、Tab只改层级前缀宽度,不影响哪些行换行
关键词大写 / 小写 / 保持原样只作用于识别出的关键字与类型名,列名和表名的大小写永不改动
IN 折行阈值1–99,默认 6元素数超过它才一行一个,填 1 等于 IN 永远折行
运算符两侧空格开 / 关控制等号、比较符周围的空格,关掉更紧凑但难读
逗号前置开 / 关逗号写在行首,加字段减字段时版本 diff 更干净
压缩时删除注释开 / 关关掉时行注释改写成块注释保留,打开则直接删掉

常见问题

  • 会不会把字符串里的分号当成语句结束?不会。只有在引号外、注释外的分号才作为语句边界。示例 SQL 里 ';已取消; 备注' 这种带分号和括号的字符串就是专门拿来验证这一点的
  • 括号不配对、引号没闭合怎么办?页面会报出大致位置(第几行、第几个字符)并停止输出,不会给你一段改坏一半的 SQL。半套结果比直接报错危险得多,因为它看起来像是能跑的
  • 压缩后的语句能直接执行吗?能。字符串与标识符原样保留,变的只有空白;行注释被改写成块注释或按选项删掉,否则 -- 会把同一行后面的内容全吃掉
  • 支持哪种方言?以 MySQL 与 PostgreSQL 的常见语法为主:反引号、方括号、带前缀字符串、:: 类型转换、窗口函数 OVER、CTE 都能识别。没有实现 $$ 美元引用和过程化脚本块,写存储过程时那部分需要自己留意
  • 表名恰好和关键字同名会被改动吗?用反引号或双引号把它包起来就一定是标识符。裸写的名字如果与关键字同形且后面紧跟左括号,按函数调用处理,不会当成子句关键词换行
  • 很大的 SQL 会不会卡?排版是单遍扫描,几十万字符也能秒级出结果。真正影响阅读的是语句条数,可以用「拆分为多条」按语句分别查看和复制
  • 数据会上传吗?不会。分词、排版、着色、复制、下载全部在页面 JS 里完成,不发任何请求,也没有服务端参与,内网离线打开照样能用
  • 美化模式和只规范空白模式差在哪?美化会重排换行与缩进;只规范空白不动你的换行位置,只把多余空格和运算符空格规整一遍,适合团队已有排版风格、只想清掉脏空格的场景

排版完要嵌进代码的 SQL,字符串拼接部分可以先用 JS 代码格式化 规整;接口返回的 JSON 用 JSON 格式化;批量整理字段清单、加注释参考 文本批量替换 与 文本行处理;对比两份 SQL 的差异用 文本对比;建表语句里的格式校验规则用 正则表达式测试 试好再写。