SQL格式化和验证器 - 在线免费格式化SQL查询
这款免费SQL格式化和验证工具能自动将关键字转换为大写、添加合理的换行和缩进,使原本杂乱的SQL语句变得清晰易读。同时它还会检测常见语法问题,例如未闭合的引号或缺少ON连接条件的JOIN语句,并给出提示,支持MySQL、PostgreSQL、SQL Server和Oracle等主流数据库方言。
SQL 格式化和验证器
使用自动缩进、关键字大写和语法错误检测来格式化和验证 SQL 查询。
文档
为什么 SQL 格式化很重要
曾经继承过一个看起来像是在蒙着眼睛输入的 SQL 数据库项目?你并不孤单。格式不规范的 SQL 是数据库开发中最常见的 bug 和时间浪费源之一。
这个 SQL 格式化器和验证器 可以帮助你自动清理混乱的查询。粘贴你的 SQL,它会立即应用适当的缩进,大写关键词,并检查语法错误——所有这些都在浏览器中完成,无需将数据发送到任何服务器。通常需要 10-15 分钟手动格式化的工作,现在只需几秒钟。
根据我在数据库团队工作的经验,最大的时间节省不仅仅是格式化——而是在问题进入生产环境之前捕获错误。一个错放的括号或未关闭的引号可能会浪费数小时的调试时间。这个工具可以立即捕获这些问题,在你对数据库执行任何操作之前。
如何使用SQL格式化工具
界面特意保持极简——直接粘贴即可:
- 将您的SQL粘贴到输入框中(如果从头开始编写,也可以直接输入)
- 在输入时自动格式化——无需点击按钮,无需配置设置
- 查看验证错误(如果格式化输出下方出现任何错误)
- 一键复制格式化的SQL,以便在IDE、文档或数据库工具中使用
在任何带浏览器的设备上都可以使用。格式化完全在客户端进行,因此您的查询永远不会离开您的机器——在处理生产数据库结构或敏感架构时尤为重要。
SQL 格式化工具的功能
关键词大写
所有 SQL 关键词都会自动大写——SELECT、FROM、WHERE、JOIN 等。这遵循了大多数数据库团队使用的约定,并使关键词与表名和列名在视觉上有所区分。当你浏览复杂的查询时,这种视觉分隔有助于你快速识别查询结构。
智能缩进
格式化工具根据逻辑层次结构来组织你的 SQL,而不是随意添加换行。主要子句如 SELECT 和 FROM 从左边距开始。JOIN 子句缩进在 FROM 下方,表明它们是表选择的一部分。子查询会有额外的缩进级别,使嵌套逻辑清晰可见。
实际上,当你有一个包含多个连接和子查询的查询时,正确的缩进让你无需阅读每个词就能看出查询结构。你可以立即看出一个连接在哪里结束,另一个在哪里开始,或者子查询在 SELECT 列表中的位置。
逻辑换行
换行出现在有助于可读性的地方,而不是到处都换行。每个主要子句都有自己的一行。逗号分隔列表中的项目(如 SELECT 中的列名)每个都有自己的行并正确缩进。子查询在视觉上是分开的。CASE 语句在 WHEN、THEN 和 ELSE 处换行,以提高清晰度。
间距遵循行业中使用的 SQL 样式指南 约定,这意味着你格式化后的 SQL 对其他开发者来说看起来很熟悉。
SQL 验证:检查什么
验证器捕获在快速编写 SQL 时通常会忽略的错误。它不会替代您数据库的查询分析器,但会在您运行查询之前捕获常见的错误。
结构性错误
不平衡的括号在具有嵌套子查询的复杂查询中出奇地常见。验证器会计算开括号和闭括号,以立即标记不匹配。我见过因在200行查询中遗漏单个括号而导致的生产事故——这可以提前捕获它们。
未关闭的字符串文字发生在您忘记在字符串值上添加闭合引号时。您的数据库将立即拒绝这些,但在这里捕获它们可以节省一次往返。
子句顺序问题在子句出现顺序不正确时被标记。例如,如果您在 GROUP BY 之前放置 HAVING,或在 GROUP BY 之后放置 WHERE,验证器会提醒您。这遵循 ISO/IEC 9075 SQL 标准中定义的 SQL 标准语法规则。
逻辑错误
没有 ON 条件的 JOIN 子句会创建意外的交叉连接,返回比预期更多的行。一个常见场景:在查询中添加第三个或第四个表时忘记 ON 子句。没有这个检查,您可能直到看到结果中有成千上万的重复行才会注意到。
没有 GROUP BY 的 HAVING 在大多数数据库中在技术上是无效的 SQL。HAVING 子句过滤分组结果,因此需要 GROUP BY 才能正常工作。验证器捕获这种逻辑不匹配。
不完整的 WHERE 条件发生在您开始输入条件但未完成时——比如 WHERE status = 没有值。在编辑查询时这些很容易被忽略。
它不会捕获的内容
此验证器专注于语法和结构,而不是数据库架构。它不会知道:
- 您的表或列名是否存在于您的数据库中
- 您是否在兼容的数据类型上进行连接
- 您的查询性能如何或是否有优化问题
- 您是否有权访问正在查询的表
将其视为在将查询发送到实际数据库之前的初步检查。
格式化规则
格式化工具基于大多数数据库团队遵循的 SQL 样式指南约定应用一致的规则。
关键词大写
每个 SQL 关键词都变成大写:SELECT、INSERT、UPDATE、DELETE、CREATE、ALTER、DROP。这包括子句(FROM、WHERE、GROUP BY、HAVING、ORDER BY)、连接类型(JOIN、INNER JOIN、LEFT JOIN)、运算符(AND、OR、NOT、IN、BETWEEN、LIKE)和常用函数(COUNT、SUM、AVG、CASE、WHEN)。
为什么使用大写?它在 SQL 的语言元素和您的数据库特定名称(表、列、别名)之间创建了视觉区分。扫描查询时,您的眼睛可以立即捕捉到结构。
每级缩进两个空格
主要子句如 SELECT 和 FROM 从左边距开始。JOIN 子句在 FROM 下缩进两个空格,表示它们是表选择的一部分。子查询每嵌套一级再缩进两个空格。这创建了与逻辑结构相匹配的视觉层次。
逗号分隔的列表(例如 SELECT 中的列名)每个都单独占一行,并保持一致的缩进。当您的 SELECT 列表有 15 个列时,这使得扫描和查找特定列变得容易。
WHERE 子句中的条件垂直对齐。当您有多个 AND 或 OR 条件时,对齐使逻辑结构立即清晰。
格式化前后:看看区别
格式化前:
1select u.id, u.name, o.order_date from users u join orders o on u.id = o.user_id where o.status = "completed" group by u.id order by u.name;
2格式化后:
1SELECT
2 u.id,
3 u.name,
4 o.order_date
5FROM users u
6 JOIN orders o ON u.id = o.user_id
7WHERE
8 o.status = "completed"
9GROUP BY
10 u.id
11ORDER BY
12 u.name;
13验证规则:哪些内容会被标记
验证器检查结构完整性和基本逻辑一致性。以下是它要检查的内容:
结构检查
平衡的括号:开括号和闭括号必须匹配。嵌套子查询通常有多层括号,误计数是最常见的SQL错误之一。验证器会为您计算括号。
正确关闭的字符串:每个开引号(单引号或双引号)都需要一个闭引号。听起来很明显,但在编写包含多个字符串文字的复杂查询时,很容易遗漏一个。
正确的子句顺序:SQL有特定的排序要求。SELECT 在 FROM 之前,FROM 在 WHERE 之前,WHERE 在 GROUP BY 之前,GROUP BY 在 HAVING 之前,HAVING 在 ORDER BY 之前。按错顺序会立即导致语法错误。验证器根据SQL标准检查这个顺序。
逻辑一致性检查
JOIN 需要 ON 条件:每个 JOIN 都需要一个 ON 或 USING 子句来指定表之间的关系。没有它,你会得到交叉连接——一个表的每一行都与另一个表的每一行配对。这很少是你想要的,通常表明缺少 ON 子句。
完整的 WHERE 条件:WHERE 子句需要完整的谓词。WHERE status = 没有值是不完整且无效的。验证器会标记这些部分条件。
HAVING 需要 GROUP BY:HAVING 子句过滤分组结果,所以只有在有 GROUP BY 时才有意义。在没有 GROUP BY 的情况下使用 HAVING 是一个逻辑错误,大多数数据库都会拒绝。
GROUP BY 聚合规则:当使用 COUNT() 或 SUM() 等聚合函数时,SELECT 列表中的任何非聚合列都必须出现在 GROUP BY 中。这是验证器检查的一个基本SQL要求。
常见错误示例
以下是验证器会标记的包含多个问题的SQL:
1SELECT user_id, COUNT(*) FROM orders
2JOIN users
3WHERE status =
4GROUP BY
5HAVING count > 10;
6检测到的问题:
JOIN users缺少ON条件(将创建交叉连接)WHERE status =不完整(没有比较值)- 空的
GROUP BY子句(未指定列) HAVING count > 10引用未定义的列
何时使用此SQL格式化工具
代码审查期间
曾经尝试过审查一个写在单行上的50行SQL查询吗?这是极其困难的。在提交查询进行代码审查之前,先通过格式化工具运行它们。你的审查者会感谢你,他们将能够专注于逻辑而不是解析结构。
在审查包含数据库更改的拉取请求时,要求贡献者先格式化他们的SQL。当结构一致时,发现逻辑错误会变得更加容易。
调试生产问题
当你在生产环境中排查一个失败的查询时,正确格式化可以帮助你清晰地看到查询结构。我已经调试了无数查询,一旦SQL被正确格式化,问题就变得显而易见——比如缺少连接条件、不正确的WHERE子句分组,或者子查询位置错误。
从日志中复制查询,粘贴到这里,你将立即看到是否存在结构性问题。
处理生成的SQL
像Hibernate、Entity Framework或SQLAlchemy这样的ORM(对象关系映射)会自动生成SQL。有时你需要查看它们实际生成的查询。生成的SQL通常是一长行且没有格式化。这个工具可以使ORM生成的查询变得可读,以便你理解和优化它们。
教学和学习SQL
如果你正在学习SQL或教授SQL,这个格式化工具可以帮助你理解正确的查询结构。当你粘贴一个有效的查询并看到它是如何格式化的,你就会学习到相关约定。当你粘贴一个有问题的查询并看到验证错误时,你就能理解为什么它不起作用。
在数据库系统间迁移
不同的数据库(PostgreSQL、MySQL、SQL Server)有略微不同的SQL方言。在系统间迁移查询时,正确的格式化可以帮助你发现可能需要调整的特定方言语法。该格式化工具遵循适用于大多数主要数据库的标准SQL约定。
SQL格式化工具的替代方案
数据库特定的集成开发环境
像DataGrip、SQL Server Management Studio或MySQL Workbench这样的工具都内置了格式化器。它们功能强大,并且可以直接与数据库连接集成。
权衡之处:它们需要安装和设置。DataGrip对个人用户收费199美元/年。SSMS是免费的,但仅限Windows系统。如果您需要快速格式化而不想安装任何软件,或者在多个数据库系统间工作,基于浏览器的工具会更实用。
编辑器扩展
如果您在VS Code或Sublime Text中编写SQL,像SQL Beautify或SqlBeautifier这样的扩展可以将格式化功能引入您的编辑器。当您正在积极编写查询并希望在工作流程中立即进行格式化时,这种方式非常有效。
局限性:扩展需要配置,并且与特定编辑器绑定。在与团队成员共享SQL或在文档中发布查询时,标准化的Web格式化工具可以确保每个人看到的格式都是一致的。
命令行格式化工具
像sqlformat(Python)或sql-formatter-cli(Node.js)这样的工具可以集成到CI/CD流水线中,以自动格式化版本控制中的SQL。这可以在团队中强制执行一致性。
最适合自动化工作流,而不是临时格式化。如果您只是想清理几个查询或学习SQL,命令行工具会增加不必要的复杂性。
SQL格式化如何成为标准实践
SQL是在1970年代由IBM开发的,但格式化约定要晚得多出现。早期的SQL是功能性的,但不一致——每个开发者以不同的方式格式化查询。
转折点出现在1990年代,当时数据库从单一开发者项目转变为团队开发。组织开始创建内部SQL样式指南以保持一致性。当五个开发者在同一个数据库上工作时,可读性强的SQL对协作变得至关重要。
2000年代带来了能自动生成SQL的ORM。这些工具生成的SQL可以运行但很丑陋——所有内容都在一行上,没有缩进。这引发了对自动格式化工具的需求,这些工具可以使生成的SQL对人类更具可读性。
在2010年代,随着Web开发的成熟,在线SQL格式化工具开始出现。开发者不再需要安装工具或配置IDE插件,而可以在浏览器中格式化SQL。这使得从初学者到经验丰富的开发者都能方便地使用正确的格式化。
如今,SQL格式化被视为基础实践,类似于其他编程语言中的代码格式化。Simon Holywell的SQL样式指南提供了广泛采用的约定,而像这样的工具可以自动实现这些标准。
代码示例
示例1:基本SELECT查询
未格式化:
1select id, first_name, last_name, email from customers where status = 'active' order by last_name, first_name;
2已格式化:
1SELECT
2 id,
3 first_name,
4 last_name,
5 email
6FROM
7 customers
8WHERE
9 status = 'active'
10ORDER BY
11 last_name,
12 first_name;
13示例2:连接查询
未格式化:
1select c.id, c.name, o.order_date, o.total_amount from customers c left join orders o on c.id = o.customer_id where o.order_date >= '2023-01-01' and o.status != 'cancelled' order by o.order_date desc;
2已格式化:
1SELECT
2 c.id,
3 c.name,
4 o.order_date,
5 o.total_amount
6FROM
7 customers c
8 LEFT JOIN orders o ON c.id = o.customer_id
9WHERE
10 o.order_date >= '2023-01-01'
11 AND o.status != 'cancelled'
12ORDER BY
13 o.order_date DESC;
14示例3:带子查询的复杂查询
未格式化:
1select d.department_name, (select count(*) from employees e where e.department_id = d.id) as employee_count, (select avg(salary) from employees e where e.department_id = d.id) as avg_salary from departments d where d.active = true having employee_count > 0 order by avg_salary desc;
2已格式化:
1SELECT
2 d.department_name,
3 (
4 SELECT
5 COUNT(*)
6 FROM
7 employees e
8 WHERE
9 e.department_id = d.id
10 ) AS employee_count,
11 (
12 SELECT
13 AVG(salary)
14 FROM
15 employees e
16 WHERE
17 e.department_id = d.id
18 ) AS avg_salary
19FROM
20 departments d
21WHERE
22 d.active = TRUE
23HAVING
24 employee_count > 0
25ORDER BY
26 avg_salary DESC;
27程序化SQL格式化
以下是在各种编程语言中实现SQL格式化的示例:
1// 使用sql-formatter库的JavaScript SQL格式化示例
2const sqlFormatter = require('sql-formatter');
3
4function formatSQL(sql) {
5 return sqlFormatter.format(sql, {
6 language: 'sql',
7 uppercase: true,
8 linesBetweenQueries: 2,
9 indentStyle: 'standard'
10 });
11}
12
13const rawSQL = "select id, name from users where status='active'";
14const formattedSQL = formatSQL(rawSQL);
15console.log(formattedSQL);
161# 使用sqlparse的Python SQL格式化示例
2import sqlparse
3
4def format_sql(sql):
5 return sqlparse.format(
6 sql,
7 reindent=True,
8 keyword_case='upper',
9 identifier_case='lower',
10 indent_width=2
11 )
12
13raw_sql = "select id, name from users where status='active'"
14formatted_sql = format_sql(raw_sql)
15print(formatted_sql)
161// 使用JSqlParser的Java SQL格式化示例
2import net.sf.jsqlparser.parser.CCJSqlParserUtil;
3import net.sf.jsqlparser.statement.Statement;
4
5public class SQLFormatter {
6 public static String formatSQL(String sql) throws Exception {
7 Statement statement = CCJSqlParserUtil.parse(sql);
8 return statement.toString()
9 .replaceAll("(?i)SELECT", "\nSELECT")
10 .replaceAll("(?i)FROM", "\nFROM")
11 .replaceAll("(?i)WHERE", "\nWHERE")
12 .replaceAll("(?i)ORDER BY", "\nORDER BY");
13 }
14
15 public static void main(String[] args) throws Exception {
16 String rawSQL = "select id, name from users where status='active'";
17 String formattedSQL = formatSQL(rawSQL);
18 System.out.println(formattedSQL);
19 }
20}
211<?php
2// PHP SQL格式化示例
3function formatSQL($sql) {
4 // 将关键字替换为大写版本
5 $keywords = ['SELECT', 'FROM', 'WHERE', 'JOIN', 'LEFT JOIN', 'RIGHT JOIN',
6 'INNER JOIN', 'GROUP BY', 'ORDER BY', 'HAVING', 'LIMIT'];
7
8 $formattedSQL = $sql;
9 foreach ($keywords as $keyword) {
10 $formattedSQL = preg_replace('/\b' . preg_quote($keyword, '/') . '\b/i', "\n$keyword", $formattedSQL);
11 }
12
13 // 添加缩进
14 $lines = explode("\n", $formattedSQL);
15 $result = '';
16 $indentLevel = 0;
17
18 foreach ($lines as $line) {
19 $trimmedLine = trim($line);
20 if (!empty($trimmedLine)) {
21 $result .= str_repeat(" ", $indentLevel) . $trimmedLine . "\n";
22 }
23 }
24
25 return $result;
26}
27
28$rawSQL = "select id, name from users where status='active'";
29$formattedSQL = formatSQL($rawSQL);
30echo $formattedSQL;
31?>
32常见问题
这个SQL格式化工具是否支持PostgreSQL、MySQL和SQL Server?
是的,它处理在主要数据库中通用的标准SQL语法——PostgreSQL、MySQL、SQL Server(T-SQL)、Oracle、SQLite和MariaDB。格式化工具专注于在各处都适用的核心SQL:SELECT、JOIN、WHERE、GROUP BY等。
数据库特定的功能可能无法完美格式化。例如,PostgreSQL的数组语法或SQL Server的专有函数可能不会得到特殊的格式化处理,但也不会破坏格式化工具。查询仍然会比原来更易读。
我的SQL代码是否会被发送到服务器?
不会。一切都在您的浏览器中进行。粘贴您的SQL,它会在本地进行格式化,不会发出任何网络请求。您的查询永远不会离开您的机器。
这一点很重要,尤其是在处理生产数据库架构或专有业务逻辑时。不存在敏感信息被记录或存储在他人服务器上的风险。
验证器能否捕获所有SQL错误?
远非如此。它只能捕获结构和语法问题——缺少括号、未关闭的引号、子句顺序错误等。仅此而已。
它无法知道您的表名是否错误、数据类型是否兼容,或查询是否需要运行10分钟。对于这些,您需要使用实际的数据库。可以将此验证器视为SQL的拼写检查,而非完整的查询分析器。
为什么要格式化SQL,当数据库无论如何都能运行它?
数据库不关心格式化——它们无论如何都会解析查询。但人类在乎。当您需要调试失败的查询、修改现有查询或审查他人的SQL时,适当的格式化会让您在30秒内理解,而不是30分钟。
格式化的SQL还有助于发现逻辑错误。当结构清晰时,您可以看出是否错误地连接了表或将条件放在了错误的位置。
我可以自定义缩进或关键字样式吗?
目前不行。格式化工具使用标准约定:大写关键字、两个空格缩进、子句单独一行。这些遵循大多数团队使用的SQL样式指南。
如果您需要自定义格式化(不同的缩进宽度、小写关键字),您需要使用可配置的命令行工具,如sqlformat,或具有格式化设置的IDE。
这对1000行存储过程有效吗?
它可以格式化大型查询,尽管非常复杂的存储过程(1000多行)可能需要几秒钟处理。格式化工具可以处理您粘贴的SQL,无论长度如何。
对于大型存储过程,您可能需要将它们拆分成更小的块,或使用针对大文件优化的数据库特定IDE。
格式化会改变查询的执行方式吗?
不会。格式化只添加空白并更改大小写。您的数据库会忽略这两者。格式化后的查询返回完全相同的结果,并以相同的性能运行。
唯一的例外是:如果验证器发现实际的语法错误(缺少括号等),修复这些错误将改变行为——但仅从"无法运行"变为"正确运行"。
这遵循哪种SQL标准?
格式化工具遵循SQL-92约定,并扩展了SQL:1999及更高版本标准的常见功能。这涵盖了大多数开发人员日常编写的SQL——SELECT查询、连接、子查询、CASE语句、窗口函数。
SQL:2016或SQL:2019中非常新的SQL功能可能无法识别,但不会破坏格式化工具。您只会得到基本格式化,而不是专门处理。
我可以将此用于Oracle PL/SQL或SQL Server T-SQL吗?
对于基本查询,可以。对于过程性代码(PL/SQL块、带有控制流的T-SQL存储过程),格式化将受限。该工具专注于SELECT、INSERT、UPDATE、DELETE语句及其子句。
如果您大量使用数据库特定的过程性代码,您的数据库原生IDE(Oracle的SQL Developer,SQL Server的SSMS)将提供更好的格式化,能够理解完整语法。
参考资料和进一步阅读
- Simon Holywell 的 SQL 风格指南 - 开发团队使用的 SQL 格式约定事实上的标准
- ISO/IEC 9075 SQL 标准 - 官方国际 SQL 标准规范
- PostgreSQL SQL 语法文档 - PostgreSQL 全面的 SQL 语法参考
- Microsoft T-SQL 参考 - SQL Server 的 T-SQL 方言官方文档
- MySQL 参考手册 - MySQL 完整的 SQL 语句参考
开始格式化您的 SQL
可读的 SQL 使调试更快、代码审查更容易,并且协作更顺畅。将您的查询粘贴到上方,即可按照行业标准约定进行格式化——无需安装、无需配置、不会有数据离开您的浏览器。