「這段查詢語句太密集了,根本讀不下去……」

正式環境系統吐出的整段擠成一行的巨大 SQL;或是巢狀 JOIN 層層堆疊、宛如迷宮的預存程序。「這個條件是在哪裡分岔的?」——盯著這樣一堵 SQL 高牆,是許多人都有過的挫折經驗。

SQL 格式化工具 會把貼上的 SQL 完全在瀏覽器內重新排版,因此即使是機密的正式環境查詢語句,也絕不會外流。

SQL 格式化工具:如何讓查詢語句變得易讀,以及方言選擇為何重要

格式化前後對照

select users.id,users.name,count(orders.id) from users left join orders on users.id=orders.user_id where users.deleted_at is null group by users.id,users.name order by users.id desc;
SELECT
  users.id,
  users.name,
  COUNT(orders.id)
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE users.deleted_at IS NULL
GROUP BY
  users.id,
  users.name
ORDER BY users.id DESC;

光是把排版整理好,遺漏的條件、JOIN 的方向、彙總的粒度就會變得清楚很多。

為什麼「方言(dialect)」的選擇是必要的,而不是可選項

SQL 格式化工具必須先進行 tokenize 並理解語法,才能決定該在哪裡換行、如何縮排。這代表各方言特有的擴充語法,會直接影響格式化能否成功。

方言差異標準 SQLMySQLPostgreSQLBigQuery
識別字引號"name"`name`"name"`project.dataset.table`
字串串接||CONCAT()||||
LIMIT 語法LIMIT nLIMIT nLIMIT n OFFSET mLIMIT n
陣列/結構非標準不支援ARRAY[...]STRUCT<...>

舉例來說,如果把 MySQL 用反引號包住的識別字當成標準 SQL 解析,token 的邊界可能會偏移,導致格式化結果整個亂掉。「格式化結果怪怪的」這類問題,大多數都是選錯方言造成的。 這個工具支援 PostgreSQL、MySQL、MariaDB、SQL Server、BigQuery 等主流方言,只要配合實際使用的資料庫選擇,切換方言時就會自動重新格式化。

SQL 審查時該檢查的重點

格式化之後,再多確認幾個項目,能進一步提升審查的品質。

  • WHERE 條件是否符合預期
  • JOIN 條件是否有遺漏
  • LEFT JOININNER JOIN 的選用是否正確(完整說明請參考 SQL JOIN 完全參考
  • GROUP BY 的彙總粒度是否符合預期
  • 需要的地方是否有加上 ORDER BYLIMIT
  • 子查詢與 CTE 是否各自承擔明確的職責

從日誌擷取出來的 SQL,通常所有預留位置都已展開,因此特別容易變長。在閱讀前先格式化,能大幅縮短調查時間。

格式化不只是讓外觀變好看

真正的價值不在於美觀,而是體現在以下三個地方:

  1. 及早發現語法錯誤——解析失敗代表某處壞掉了,等於是執行前的免費健檢
  2. 讓 diff 更穩定——固定格式化規則後,查詢變更的 diff 只會反映真正有意義的修改
  3. 解讀機器產生的 SQL——ORM 吐出的單行查詢,格式化之後才看得出它到底 JOIN 了什麼

第一點特別容易被忽略:括號數量不對、少了逗號這類失誤,會直接讓格式化處理失敗,讓您在執行前就能發現問題。

常見問題

支援 MySQL 和 PostgreSQL 的 SQL 嗎?

支援。標準 SQL、MySQL、PostgreSQL、MariaDB、SQL Server、BigQuery 等主流方言都可以格式化。若 SQL 中含有方言特有的語法,執行前仍請務必自行確認。

格式化會改變 SQL 的意義嗎?

不會。格式化只會調整空白、換行、縮排、關鍵字大小寫,查詢的意義(執行結果)不會改變。不過執行前,還是建議務必確認格式化後的版本與原意一致。

選錯方言會發生什麼事?

識別字的引號方式或關鍵字的解讀可能會跑掉,導致縮排錯亂或出現預期外的換行。如果覺得「格式化結果怪怪的」,請先檢查方言選擇是否正確。

貼上含有機密資料的 SQL 安全嗎?

安全。格式化完全在瀏覽器內完成,不會有任何網路連線,資料表名稱與欄位名稱都不會外流。

總結

  • 格式化工具本身只是把工作委派給函式庫的一行程式碼,但方言選擇才是真正決定結果的關鍵參數
  • 光是識別字引號的差異,就可能改變查詢的解析方式,請依實際使用的資料庫選擇方言
  • 格式化不只是美觀而已:能及早發現語法錯誤、穩定 diff、解讀機器產生的 SQL

下次從日誌中挖出查詢語句時,不妨先丟進格式化工具看看。