SQL Query Analyzer
Paste SQL for a quick heuristic check: UPDATE or DELETE without WHERE, SELECT *, implicit cross joins, unbounded selects and N+1 patterns. It is pattern matching, not a parser, so treat each finding as a prompt to look closer.
Regex-powered safety checks over your statements: destructive writes without WHERE, SELECT *, implicit cross joins, unbounded reads, and N+1 smells. Positions are line-rough.
What the analyzer catches, and what it misses
Each example was analyzed by this page's own checks when the site was built. The misses are listed on purpose: knowing that a WHERE 1=1 slips through, or that DROP is never checked, is what lets you trust the findings it does report.
UPDATE without WHERE
The finding that justifies the tool: one missing clause rewrites every row.
SQL
UPDATE users SET trial = 0;
Findings
- ERROR Missing WHERE clause — this statement rewrites or deletes the entire table.
The same UPDATE with a WHERE
With a WHERE clause there is nothing to report.
SQL
UPDATE users SET trial = 0 WHERE id = 7;
Findings: none
A WHERE that matches every row
Not caught. The check looks for a WHERE clause, not at what it selects. This is pattern matching, not a parser.
SQL
DELETE FROM logs WHERE 1=1;
Findings: none
SELECT *
Two findings: every column is fetched, and nothing bounds the number of rows.
SQL
SELECT * FROM orders;
Findings
- WARN SELECT * pulls every column — list only the columns you need.
- INFO No LIMIT and no aggregate — result set is unbounded.
An implicit cross join
Two tables listed with a comma and no WHERE pair every row of one with every row of the other.
SQL
SELECT a.id FROM a, b;
Findings
- WARN Comma-separated FROM without WHERE produces an implicit CROSS JOIN (Cartesian product).
- INFO No LIMIT and no aggregate — result set is unbounded.
A primary-key lookup
Flagged as unbounded although it returns at most one row. The analyzer cannot see your schema, so treat info findings as prompts.
SQL
SELECT email FROM customers WHERE id = 1;
Findings
- INFO No LIMIT and no aggregate — result set is unbounded.
A bounded or aggregate query
An aggregate returns one row, so it is not flagged; the same goes for a query with LIMIT.
SQL
SELECT COUNT(*) FROM orders;
Findings: none
Keywords inside a string literal
Text inside quotes is not read as SQL, so the DELETE in the string is ignored.
SQL
SELECT id FROM notes WHERE body = 'DELETE FROM x' LIMIT 5;
Findings: none
The same lookup run in a loop
Repeated single-row selects on one table are the shape of an N+1 query, typical of an ORM loading related rows one at a time.
SQL
SELECT email FROM customers WHERE id = 1; SELECT email FROM customers WHERE id = 2; SELECT email FROM customers WHERE id = 3;
Findings
- INFO No LIMIT and no aggregate — result set is unbounded.
- INFO Table "customers" selected 3 times across statements — classic N+1; batch with IN (...) or a JOIN.
- INFO No LIMIT and no aggregate — result set is unbounded.
- INFO No LIMIT and no aggregate — result set is unbounded.
TRUNCATE and DROP
Not flagged: these statements are outside the checks, however destructive. Review them yourself.
SQL
TRUNCATE TABLE logs; DROP TABLE users;
Findings: none