SQL 格式化与方言转换

格式化 SQL,并在 MySQL、PostgreSQL、SQLite 之间互转。每一处改写都列出来,改不动的明说改不动、绝不猜 —— 全部在你的浏览器里完成。

同时提供 Windows 桌面版。

关于这个工具

SQL 看着挺通用,大部分时候也确实通用 —— 直到某一天不通用为止。同一条语句在 MySQL 和 PostgreSQL 里可以有不同含义,而这些差异恰好都是**不报错**的那一类:PostgreSQL 把 "name" 当列名,MySQL 把它当字符串;`||` 在 MySQL 里是"或",在 PostgreSQL 里是"拼接"。没改就搬过去的查询照样能跑、照样返回行 —— 返回的是错的行。

这个工具做两件事。一是排版:让每个子句、每个列表项、每个布尔条件各占一行。二是在 MySQL、PostgreSQL、SQLite 之间互转。它做的**每一处改写都列出前后原文**,所以你可以核对,而不是只能相信。

凡是"不猜你意图就没法翻译"的地方,它一律不动,只列在「需要你手工处理」里:`::` 强转、各种 UPSERT 写法、ILIKE、AUTO_INCREMENT、存储引擎选项。在这些地方猜,产出的是**语法合法但语义已变**的 SQL,比直接报错更危险。所有计算都在你的浏览器里完成,粘贴的 SQL 不会发往任何地方。

常见问题

排版会不会改变 SQL 的行为?
不会。排版只移动空白、把保留字改成大写,绝不增删或重排任何一个 token。这条由测试盯着:把排版结果重新分词,要求 token 序列与输入完全一致 —— 所以少一个空格这种事不可能溜过去。
为什么有些地方宁报警也不翻译?
因为有些差异必须先知道你想表达什么。MySQL 的 `||` 是逻辑或,PostgreSQL 里同样的符号是拼接;MySQL 的 "abc" 是字符串,PostgreSQL 里是列名。不存在对两种读法都正确的改写,所以工具拒绝替你选,改为告诉你。
MySQL 的 LIMIT 50, 25 和 LIMIT 25 OFFSET 50 是一回事吗?
是。MySQL 额外接受 `LIMIT offset, row_count` 这种简写,PostgreSQL 和 SQLite 只认 `LIMIT row_count OFFSET offset`。从 MySQL 转出去时,工具会把简写改写成标准形式。
ON DUPLICATE KEY UPDATE 和 ON CONFLICT 为什么不直接互转?
因为两者不等价。ON CONFLICT 必须写明**冲突目标**(哪几列或哪个约束触发合并),而 ON DUPLICATE KEY 依赖的是表上恰好存在哪些唯一索引 —— 这个信息不在语句里,推导不出来。目标列必须由你来点。
能转换存储过程或整库导出的文件吗?
不可靠。存储过程、触发器和各家的建表扩展携带的方言细节远超一个格式化工具能跟踪的范围,而在这些地方改错的代价很高。建议只用它处理查询和简单建表语句,并把「需要你手工处理」里列的每一条都当成真的需要你判断。
我的 SQL 会被发到服务器上吗?
不会。整个工具都是跑在页面里的普通 JavaScript —— 没有服务端、不发请求、不记录。页面加载完之后断网也能用,你可以自己用这个办法验证。

相关工具