Fydler UtilityBelt
SQL Formatter
Data & Formatting Tool
SQL Input
Formatted SQL
Copy
Formatting Rules
Major keywords (SELECT, FROM, WHERE, JOIN, etc.) start on new lines
Conditions (AND, OR) are indented with 2 spaces
JOIN clauses are indented for readability
Copied to clipboard!
lucide.createIcons(); const input = document.getElementById('sql-input'); const output = document.getElementById('sql-output'); function formatSQL(sql) { const keywords = ['SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'SET', 'DELETE', 'CREATE', 'TABLE', 'ALTER', 'DROP', 'INDEX', 'JOIN', 'LEFT', 'RIGHT', 'INNER', 'OUTER', 'ON', 'AS', 'ORDER BY', 'GROUP BY', 'HAVING', 'LIMIT', 'OFFSET', 'UNION', 'ALL', 'DISTINCT', 'CASE', 'WHEN', 'THEN', 'ELSE', 'END', 'EXISTS', 'IN', 'NOT', 'NULL', 'IS', 'BETWEEN', 'LIKE', 'COUNT', 'SUM', 'AVG', 'MIN', 'MAX', 'ASC', 'DESC', 'BY', 'INNER JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'FULL JOIN', 'CROSS JOIN', 'OUTER JOIN', 'NATURAL JOIN']; let upper = sql.toUpperCase().trim(); // Normalize whitespace upper = upper.replace(/\s+/g, ' '); // Add newlines before major keywords const majorKeywords = ['SELECT', 'FROM', 'WHERE', 'AND', 'OR', 'ORDER BY', 'GROUP BY', 'HAVING', 'LIMIT', 'OFFSET', 'UNION', 'INNER JOIN', 'LEFT JOIN', 'RIGHT JOIN', 'FULL JOIN', 'CROSS JOIN', 'OUTER JOIN', 'NATURAL JOIN', 'JOIN', 'ON']; for (const kw of majorKeywords) { const re = new RegExp('\\b' + kw + '\\b', 'gi'); upper = upper.replace(re, '\n' + kw); } // Indent JOIN conditions let lines = upper.split('\n').map(l => l.trim()); let result = []; let indent = 0; for (let line of lines) { const upperLine = line.toUpperCase().trim(); if (upperLine.startsWith(')')) indent = Math.max(0, indent - 1); let prefix = ''; if (upperLine.startsWith('AND') || upperLine.startsWith('OR') || upperLine.startsWith('ON')) { prefix = ' '; } if (upperLine.startsWith('INNER') || upperLine.startsWith('LEFT') || upperLine.startsWith('RIGHT') || upperLine.startsWith('FULL') || upperLine.startsWith('CROSS') || upperLine.startsWith('OUTER') || upperLine.startsWith('NATURAL') || upperLine.startsWith('JOIN')) { prefix = ' '; } result.push(prefix + line); if (upperLine.startsWith('SELECT') || upperLine.startsWith('INSERT') || upperLine.startsWith('UPDATE')) { // no indent } } return result.join('\n'); } function update() { const val = input.value.trim(); if (!val) { output.value = ''; return; } try { output.value = formatSQL(val); } catch(e) { output.value = 'Error: ' + e.message; } } input.addEventListener('input', update); document.getElementById('sql-copy-btn').addEventListener('click', () => { const v = document.getElementById('sql-output').value; if (v) { navigator.clipboard.writeText(v); showToast('Copied!'); } }); function showToast(msg) { const toast = document.getElementById('toast'); const toastMsg = document.getElementById('toast-message'); toastMsg.textContent = msg; toast.classList.add('show'); setTimeout(() => toast.classList.remove('show'), 2000); }