跳到主要内容
Tooletto

SQL 格式化工具

格式化 SQL 查询,让每个子句独占一行,并对列表和嵌套子查询进行缩进。字符串字面量里的关键字会被原样保留,这正是简单的格式化工具容易出错的地方。

  • 文件永不离开你的设备
  • 免费,无需注册
  • 无水印
  • 加载后可离线使用
Loading tool…

如何SQL 格式化工具

  1. 1

    粘贴你的查询语句

    一整行密集的,或者已经半格式化过的都可以。

  2. 2

    设置你的偏好

    缩进大小,以及关键字是否要大写。

  3. 3

    复制结果

    可以直接粘贴回你的编辑器或迁移脚本里。

让基于正则表达式的 SQL 格式化工具出错的那个具体 bug

一个通过正则表达式全字匹配来大写关键字的格式化工具,没有办法知道某一处出现的 "order" 到底是 SQL 关键字 `ORDER`(比如 `ORDER BY` 里的那个),还是恰好包含这个单词的一段字符串字面量——一条筛选 `WHERE description = 'the order from stock'` 的查询,里面的 "order" 是躺在一个带引号的字符串内部,根本不是在起关键字的作用。一个简单的格式化工具会不分场合地大写每一处匹配的单词,把这段字符串字面量破坏成 `'the ORDER FROM stock'`,悄悄改变了这条查询实际筛选的内容。正确地对查询语句分词——在判断什么算关键字之前先识别出带引号字符串的边界——正是防止这种情况的关键,而这恰恰是那种只有在包含了恰好和 SQL 关键字撞车的单词的真实数据上才会显现出来的 bug,这也是为什么它在用简单示例查询测试时很容易被漏掉。

"只格式化不解析"在实践中意味着什么

这个工具能识别 PostgreSQL、MySQL、SQL Server、SQLite 和 Oracle 共有的常见子句结构——SELECT、FROM、WHERE、JOIN、GROUP BY、ORDER BY 以及它们的近亲——足以把每个子句缩进到自己的一行,并正确嵌套子查询。它不会去构建对任何一个具体数据库完整语法的全面理解,包括像 PostgreSQL 的数组语法或者 SQL Server 的 `TOP` 子句位置这类特定厂商的扩展语法。实际的结果是,特定方言的语法会原样通过这个格式化工具而不会报错,但它也不会得到常见子句那样细致的缩进处理——用一个格式化工具支持五种方言,这是一个合理的取舍,好过为每个数据库引擎单独配一个工具。

为什么格式化不可能改变一条查询实际执行的结果

SQL 关键字在语言规范本身里就是不区分大小写的——`SELECT`、`Select` 和 `select` 对每一个 SQL 引擎来说都是完全相同的——这正是让大写或小写它们变成一个纯粹表面操作、完全没有改变行为风险的原因。这个格式化工具添加的空白和换行也是同样的道理:一条分散在十二行、带有缩进的查询,和挤在一行里的同一条查询,执行结果完全相同。格式化不会触碰任何决定要读取哪些表、用什么条件筛选行,或者插入什么值的实际标记——它改变的只是同一条逻辑查询,事后呈现给阅读它的人时的视觉排布方式。

阅读一条冗长的迁移脚本或自动生成的查询语句

一条由 ORM 生成、从数据库图形界面导出,或者在一次仓促的迁移中写成一整行铺开的查询语句,往往在功能上是正确的,但对一个人来说照原样阅读确实很困难——一条包含十五个连接、没有任何换行的查询,很难看清哪些条件属于哪个连接,或者一个 WHERE 子句到底是不是在筛选正确的表。把它重新格式化,让每个子句和每个连接都独占一行,并按查询实际的结构缩进,往往是在代码审查中真正批准它之前、或者在调试它为什么返回了错误的行之前,理解一条冗长的自动生成查询到底在做什么最快的办法。

常见问题

会改变我的查询实际执行的逻辑吗?

不会。只有空白和关键字的大小写会改变——没有任何子句被重新排序,也没有任何标记被重写。SQL 关键字本身是不区分大小写的,所以把它们大写不可能改变行为。

引号里面的文字会怎样?

会被原样保留。这个格式化工具在触碰任何内容之前会先对查询语句做分词,所以像 'check the order from stock' 这样的字符串会保留它原本小写的 "order" 和 "from",而不会被当成关键字大写。基于正则表达式的格式化工具经常在这一点上出错。

支持哪些 SQL 方言?

PostgreSQL、MySQL、SQL Server、SQLite 和 Oracle 共有的常见子句结构。它是做格式化而不是做解析,所以特定方言的语法会原样通过而不会报错——但也不会得到特别的缩进处理。

我的查询语句会被发送到别处吗?

不会。格式化在你的浏览器中进行。这一点很重要,因为真实的查询语句往往携带表名、列名,有时甚至是字面意义上的客户数据——这些都不该被粘贴进一个陌生的服务器。

SQL 格式化工具常见任务