SQL フォーマッター&方言コンバーター

SQL を整形し、MySQL・PostgreSQL・SQLite の間で変換します。書き換えた箇所はすべて一覧表示し、安全に変換できない箇所は推測せずに指摘します。処理はすべてブラウザ内で完結します。

Windows デスクトップ版もあります。

このツールについて

SQL は一見どこでも動くように見えます。実際、たいていは動きます — 動かなくなるまでは。同じ文が MySQL と PostgreSQL で別の意味になることがあり、しかもその差は**エラーにならない**種類ばかりです。PostgreSQL は "name" を識別子として読み、MySQL は文字列として読みます。`||` は MySQL では論理和、PostgreSQL では文字列連結です。直さずに移したクエリは動き続け、行を返し続けます — 間違った行を。

このツールは 2 つのことをします。1 つは整形:各句、各リスト項目、各ブール条件をそれぞれ別の行にします。もう 1 つは MySQL・PostgreSQL・SQLite 間の変換です。行った**すべての書き換えは変更前と変更後を並べて表示**しますので、信じるのではなく確認できます。

「意図を推測しないと翻訳できない」箇所は一切手を触れず、「手作業が必要な箇所」として列挙するだけにしています:`::` キャスト、各種 UPSERT 構文、ILIKE、AUTO_INCREMENT、ストレージエンジンのオプション。こうした箇所で推測すると、**文法的には正しいが意味の違う** SQL ができあがり、エラーよりも危険です。処理はすべてブラウザ内で完結し、貼り付けた SQL はどこにも送信されません。

よくある質問

整形で SQL の動作は変わりますか?
変わりません。整形は空白を動かし、予約語を大文字にするだけで、トークンを追加・削除・並べ替えることは一切しません。これはテストで担保しています:整形結果を再びトークン化し、入力と同じトークン列であることを要求しています。空白が 1 つ抜けるといった事故は通り抜けられません。
なぜ一部は翻訳せずに警告だけするのですか?
意図を知らないと正しく訳せない差異があるからです。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 はテーブルにたまたま存在する一意インデックスに依存します。その情報は文の中にないため導出できません。対象列はご自身で指定してください。
ストアドプロシージャやスキーマ全体のダンプも変換できますか?
信頼できる変換はできません。プロシージャ、トリガー、各社固有の DDL はフォーマッターが追跡できる以上の方言の細部を含み、そこで書き換えを誤ると代償が大きいからです。クエリと単純な DDL に使うことをお勧めします。また「手作業が必要な箇所」に挙がった項目は、本当にご自身の判断が必要なものとして扱ってください。
入力した SQL はどこかに送信されますか?
いいえ。すべてページ内で動くただの JavaScript です — サーバーも、リクエストも、ログもありません。読み込み後はオフラインでも動作しますので、その気になればご自身で確かめられます。

関連ツール