跳至内容

SQL格式化和验证器 - 在线免费格式化SQL查询

这款免费SQL格式化和验证工具能自动将关键字转换为大写、添加合理的换行和缩进,使原本杂乱的SQL语句变得清晰易读。同时它还会检测常见语法问题,例如未闭合的引号或缺少ON连接条件的JOIN语句,并给出提示,支持MySQL、PostgreSQL、SQL Server和Oracle等主流数据库方言。

SQL 格式化和验证器

使用自动缩进、关键字大写和语法错误检测来格式化和验证 SQL 查询。

输入 SQL 查询以查看格式化结果。
加载计算器...
📚

文档

SQL 格式化器和验证器是什么?

SQL 格式化器是一种工具,它会用一致的空格、换行和大写关键字重写 SQL 查询,使其更易于阅读。SQL 验证器会在不连接数据库的情况下,检查同一个查询是否存在结构错误,例如未闭合的引号或缺失的括号。此工具同时具备这两种功能。它完全在浏览器中运行,因此查询文本不会发送到服务器。

如何格式化 SQL 查询

  1. 将 SQL 查询粘贴或输入到输入框中。
  2. 格式化后的版本会自动显示在右侧,无需点击按钮。
  3. 所有验证错误都会显示在输出下方的列表中。
  4. 点击复制按钮即可将格式化后的查询发送到剪贴板。

SQL 格式化规则

关键字大小写

格式化器会将固定列表中的 SQL 关键字改为大写,但仅限于它们出现在字符串或带引号的标识符之外的情况。该列表包括主要子句(SELECT、FROM、WHERE、GROUP BY、ORDER BY、HAVING、LIMIT、OFFSET)、连接词(JOIN、LEFT、RIGHT、INNER、OUTER、FULL、CROSS、NATURAL、ON、USING)、集合运算符(UNION、INTERSECT、EXCEPT)、语句类型(INSERT、UPDATE、DELETE、CREATE、ALTER、DROP),以及常见运算符和连接词(AND、OR、NOT、IN、BETWEEN、LIKE、AS、CASE、WHEN、THEN、ELSE、END、ALL、DISTINCT、VALUES、SET,以及其他几个关键字)。

一些看起来像关键字的词会保持输入时的形式。聚合函数(如COUNT、SUM和AVG)不在列表中,因此如果输入时使用小写,count(*)也会保持小写。排序方向词ASC和DESC,以及单独出现的字面量TRUE、FALSE和NULL也不会改变。字符串字面量('...')、带引号的标识符("..."、`...`或[...])以及注释中的文本,无论包含什么内容,都不会被修改。

换行和缩进

每个主要子句都从左边界的新行开始:SELECT、FROM、WHERE、GROUP BY、ORDER BY、HAVING、LIMIT和OFFSET。连接操作整体从新行开始,因此LEFT JOIN、FULL OUTER JOIN和CROSS JOIN会保持在一起,不会拆分到两行。UNION和UNION ALL的上方和下方各有一个空行,用于分隔它们合并的查询。CASE和END从新行开始,WHEN、THEN和ELSE从缩进后的新行开始。每个逗号也会开始新行,因此SELECT或GROUP BY中的列列表最终会每行显示一列。

缩进只出现在括号内部。子查询或分组表达式中的内容会根据嵌套层级,每层缩进两个空格。没有括号的查询——日常查询中的大多数情况——会让每个子句都紧贴左边界,完全不缩进。

示例:格式化前后

格式化前:

1select id, first_name, last_name, email from customers where status = 'active' order by last_name, first_name;
2

格式化后:

1SELECT id,
2first_name,
3last_name,
4email
5FROM customers
6WHERE status = 'active'
7ORDER BY last_name,
8first_name;
9

每个关键字都是大写,每个子句和列都单独占一行。由于查询没有括号,因此没有任何行缩进。

括号会改变这种情况。将(select count(*) from employees e where e.department_id = d.id)作为较大查询的一部分进行格式化时,内部的SELECT、FROM和WHERE会缩进两个空格;count则保持小写,因为它是函数名,不是列表中的关键字。

SQL 验证器检查什么

验证器会在不连接数据库的情况下查找结构问题:

  • 未闭合的引号、括号和注释。 已打开但始终未闭合的单引号(')、双引号(")、反引号(`)、方括号([)或块注释(/*)。
  • 括号不平衡。 字符串和注释之外的(与)数量必须相同。
  • 没有使用括号的子查询。 位于所有括号之外的第二个SELECT,例如SELECT * FROM SELECT id FROM t。由集合运算符(UNION、UNION ALL、INTERSECT、EXCEPT)连接的两个查询不会被标记,因为这些操作数不需要括号。用分号分隔的两个语句也不会被标记。
  • 以AND或OR开头的WHERE。 开头的连接词前没有任何内容。
  • 没有匹配条件的JOIN。 JOIN需要ON或USING子句。CROSS JOIN和NATURAL JOIN不受此规则限制,因为它们不需要条件。
  • 空的GROUP BY或ORDER BY。 查询末尾只有子句关键字,后面没有列名。
  • 不完整的WHERE条件。 查询末尾存在没有值的悬空比较,例如WHERE status =,或单独的WHERE后面没有任何内容。
  • 没有FROM的SELECT。 仅当选择列表是普通列名时才会标记。表达式、函数调用、字面量或不带括号书写的值函数(例如CURRENT_DATE)可以单独使用,因此SELECT 1 + 1和SELECT CURRENT_DATE不会被标记。
  • 子句顺序。 检查两种具体情况:GROUP BY不得出现在WHERE之前,ORDER BY不得出现在GROUP BY之前。这些检查只针对查询的顶层,不考虑子查询内部的内容。

不检查的内容

验证器无法判断表或列是否确实存在、连接列的类型是否兼容,也无法判断查询的执行性能。它也不会标记真实数据库执行的每一条规则。例如,不带GROUP BY而使用HAVING是可以接受的,因为将整个结果分成一个隐式分组符合 SQL 规则,所以验证器不会因此报错。同样,它不会检查SELECT列表中的每个非聚合列是否也出现在GROUP BY中——大多数数据库都有这条规则,但此工具不会进行检查。缺少末尾分号也不会被标记,因为分号是语句分隔符,而不是单个查询的一部分。

示例:验证器能捕获的错误

1SELECT id FROM orders
2JOIN users
3WHERE status =
4

此查询会产生两个错误:

  1. “一个或多个 JOIN 语句缺少 ON 条件。”——JOIN users没有ON或USING子句。
  2. “WHERE 条件不完整。”——status =的等号后没有值。

常见问题

此工具适用于 MySQL、PostgreSQL、SQL Server 和 Oracle 吗?

它支持这些数据库共有的核心 SQL 语法:SELECT、JOIN、WHERE、GROUP BY及类似子句。数据库特有的语法,例如 PostgreSQL 数组字面量或 T-SQL 过程块,不会导致格式化器出错,但可能不会得到特殊处理。

SQL 查询会发送到服务器吗?

不会。格式化和验证都在浏览器中运行。查询文本不会被传输到任何地方。

它会将 COUNT、SUM 和 AVG 等函数名改为大写吗?

不会。只有子句关键字、连接词和固定列表中的运算符会改为大写。函数名(如count、sum和avg)以及asc、desc、true、false和null这些词都会保持输入时的形式。

验证器会标记不带 GROUP BY 的 HAVING 吗?

不会。不带GROUP BY的HAVING子句会将整个结果分成一个分组;根据 ISO/IEC 9075标准,这是有效的 SQL,因此验证器不会将其视为错误。

验证器能捕获所有 SQL 错误吗?

不能。它会检查结构——括号、引号、少数子句顺序规则,以及一些常见的逻辑缺失,例如没有条件的JOIN。它不会检查表名、列名、数据类型或查询性能。要确认查询能否正确运行,仍然需要连接真实数据库。

格式化会改变查询的运行方式吗?

不会。格式化只会改变空白字符以及未加引号关键字的大小写。字符串、带引号的标识符或注释中的任何内容都会原样复制,因此查询的含义与格式化前完全相同。

参考文献