data / sql

SQLフォーマッター

SQLをキーワード大文字化・インデント整形・圧縮できます。入力データはサーバーに送信されません。

// 整形・圧縮ボタンを押すと結果がここに表示されます

使い方

01
  1. 左側のテキストエリアにSQLをペーストしてください
  2. 「整形」ボタンを押すとキーワードが大文字化され、各句が改行・インデントされます
  3. 「圧縮」ボタンを押すとコメントを除去して1行に圧縮できます
  4. 右側に結果が表示されたら「コピー」ボタンでクリップボードにコピーできます
  5. 「クリア」ボタンで入力・出力を一括リセットできます

実装コード

02

コアロジックはブラウザ標準APIのみで実装しています。正規表現ベースのトークナイザーでSQLを字句解析し、キーワードの種類に応じて改行・インデントを挿入します。外部ライブラリは不要なので、そのままコピーしてご利用いただけます。

export function formatSql(sql: string, indent: string = '  '): FormatResult {
  if (!sql.trim()) return { ok: false, error: '入力が空です' }
  try {
    const tokens = tokenize(sql)
    const words = tokens.map(t => {
      if (t.kind === 'whitespace' || t.kind === 'comment') return t
      const up = t.value.toUpperCase()
      if (KEYWORDS.includes(up)) return { kind: 'keyword' as TokenKind, value: up }
      return t
    })
    const multiKeywords = KEYWORDS
      .filter(k => k.includes(' '))
      .sort((a, b) => b.length - a.length)

    let out = ''
    let depth = 0
    const nonWS = words.filter(t => t.kind !== 'whitespace')

    for (let idx = 0; idx < nonWS.length; idx++) {
      const t = nonWS[idx]
      // multi-word keyword check (ORDER BY, LEFT JOIN, ...)
      let matched = ''
      for (const mk of multiKeywords) {
        const parts = mk.split(' ')
        let ok = true
        for (let p = 0; p < parts.length; p++) {
          const nt = nonWS[idx + p]
          if (!nt || nt.value.toUpperCase() !== parts[p]) { ok = false; break }
        }
        if (ok) { matched = mk; break }
      }
      if (matched) {
        if (NEWLINE_BEFORE.has(matched)) {
          out = out.trimEnd()
          out += '\n' + indent.repeat(depth > 0 ? 1 : 0) + matched
        } else {
          out += ' ' + matched
        }
        idx += matched.split(' ').length - 1
        continue
      }
      if (t.kind === 'keyword' && NEWLINE_BEFORE.has(t.value)) {
        out = out.trimEnd()
        out += '\n' + indent.repeat(depth > 0 ? 1 : 0) + t.value
      } else if (t.kind === 'paren') {
        if (t.value === '(') { out += '('; depth++ }
        else { depth = Math.max(0, depth - 1); out = out.trimEnd(); out += ')' }
      } else if (t.kind === 'comma') {
        out += ','
        out += depth <= 1 ? '\n' + indent : ' '
      } else {
        out += ' ' + t.value
      }
    }
    return { ok: true, output: out.trim() }
  } catch (e) {
    return { ok: false, error: `フォーマットエラー: ${String(e)}` }
  }
}

よくある使用例・注意点

03
クエリのレビュー・共有時に
ORM や BI ツールが生成した1行の長いSQLを整形して、レビューや共有に使えます。JOIN条件やWHERE句の論理が一目でわかるようになります。
本番環境へのデプロイ前の圧縮
アプリケーションのコードに埋め込むSQLは圧縮してスペースを節約できます。コメント・余分な空白を除去した最小化されたSQLを生成します。
方言による違いに注意
このツールはSQL標準のキーワードを対象に整形します。MySQL固有の構文(LIMIT ... OFFSET)やPostgreSQL拡張などは認識できないキーワードが出ることがありますが、文字列・識別子はそのまま保持されます。
文字列リテラル・識別子は変換しない
シングルクォート・ダブルクォートで囲まれた文字列リテラルや、バッククォートで囲まれた識別子の内容は大文字化・改行の対象外です。データ値がそのまま保持されます。

関連ツール

04
JSONフォーマッター文字数カウンター正規表現テスター

ソースコード

05

このツールのソースコード(テストコードを含む)はGitHubで公開しています。 MITライセンスで自由に利用・改変できます。

GitHub でコードを見る →