SQL validator for 13 dialects
This SQL validator parses your statements with a full SQL grammar and tells you whether they are syntactically valid for the dialect you choose. When something is wrong, it points to the exact line and column, prints the offending line with a caret under the problem, and lists the tokens the parser expected at that spot. When everything parses, it lists each statement type and every table the query touches.
What does a SQL syntax checker catch?
A syntax check finds the mistakes that stop a query before the database even plans it: misspelled keywords (FORM instead of FROM), missing commas between columns, unbalanced parentheses, a stray trailing comma before FROM, unclosed string quotes, and clauses in the wrong order, such as WHERE after GROUP BY. It is useful before running a migration, when reviewing SQL in a pull request, or when a long generated query fails with a vague error.
Example: valid query
The three-table join from the sample returns:
✔ Valid MySQL syntax — 1 statementStatements:1. SELECTTables referenced:orders — selectcustomers — selectorder_items — select
Example: finding an error
For SELECT name FORM users; the validator reports:
Syntax error at line 1, column 18: Expected "#", ",", "--", "/*", ";","COLLATE", "EXCEPT", "FOR", "FROM", ... or end of input but "u" found.SELECT name FORM users;^Notice where the caret lands. The parser happily read FORM as a column alias (SELECT name AS FORM), so the real failure shows up one word later, at users. Syntax errors are often reported just after the actual typo, so look at the token before the caret as well.
Supported dialects
Choose from MySQL, MariaDB, PostgreSQL, SQLite, SQL Server (T-SQL), BigQuery, Snowflake, Redshift, Hive, IBM Db2, Flink SQL, Trino and Athena. The dialect matters: SELECT TOP 5 name FROM users is valid T-SQL but fails as MySQL, which uses LIMIT instead. Likewise, PostgreSQL-only operators like ILIKE or :: casts should be checked with the PostgreSQL setting.
You can validate SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, ALTER TABLE, DROP and other common statements, several at a time.
What it cannot check
- Schema: the validator does not connect to your database, so it cannot tell whether a table or column exists, whether types match, or whether you have permission.
- Logic: a query can be valid and still return the wrong rows, for example a
LEFT JOINturned into an inner join by aWHEREcondition. - Every vendor extension: the grammar covers the widely used syntax of each dialect, but rare features such as stored procedure bodies may be reported as errors even though your server accepts them. The parser can also be more lenient than your server in places.
For a final check, run the statement with EXPLAIN on a development database. That confirms both syntax and schema without changing any data.
Privacy
Validation runs entirely in your browser; your SQL is not sent to a server or a database. Once the query is valid, clean up its layout with the SQL formatter, compress it with the SQL minifier, or translate it with SQL to MongoDB.
SQL validator in Python
Python's standard library has no general SQL parser, so a syntax check needs a package. sqlglot parses MySQL, PostgreSQL (postgres), T-SQL (tsql) and other dialects, and raises ParseError with the line and the offending token. The usual mistake is reaching for sqlparse: it is a non-validating parser that splits and formats statements but does not raise on broken SQL.
# pip install sqlglot
import sqlglot
from sqlglot.errors import ParseError
def validate(sql, dialect="mysql"):
try:
statements = sqlglot.parse(sql, dialect=dialect)
except ParseError as err:
first = err.errors[0]
return f"Invalid: line {first['line']}, near {first['highlight']!r}"
return f"Valid: {len(statements)} statement(s)"
print(validate("SELECT id, name FROM users WHERE id = 7"))
print(validate("SELECT name FORM users"))
print(validate("SELECT TOP 5 name FROM users"))
print(validate("SELECT TOP 5 name FROM users", dialect="tsql"))
The script and the validator above agree on these four queries. sqlglot is forgiving in places, though: it accepts SELECT id, FROM users, which this page reports as a syntax error, so paste a query here for a stricter second check before you format the SQL.