SQL generation prompt builder
The fastest way to make an LLM write correct SQL is to stop letting it guess your schema. When the model knows your exact table names, columns, and foreign keys, the most common failure — referencing objects that do not exist — disappears. This builder takes your DDL, parses out the schema, and wraps it in a system prompt tuned to your SQL dialect so natural-language questions return runnable queries.
How it works
Paste your CREATE TABLE statements (or a simple table.column list) and the
tool extracts the table and column names, echoing them back as a compact schema
the model must respect. It then layers in dialect rules — for example,
Postgres uses double-quoted identifiers and LIMIT, MySQL uses backticks,
SQLite is forgiving but lacks some functions — plus standing instructions to
use only listed columns, qualify ambiguous names, and return a single query. Any
sample queries you provide are appended as few-shot examples to anchor the
model’s join logic.
Why schema grounding is the key lever
Without a real schema, an LLM generating SQL faces an impossible task: it must invent table and column names from the natural-language question. This produces SQL that is plausible-looking but references objects that do not exist — queries that fail immediately when you run them. More subtly, even when a model guesses a column name that exists, it may get the casing wrong or choose the wrong table when two tables have similar column names.
Pasting your actual DDL closes this gap almost entirely. The model can only reference objects you provided, and the prompt explicitly instructs it not to invent columns or tables that are not in the schema.
Dialect differences that matter
PostgreSQL uses double-quoted identifiers (necessary when names contain uppercase letters or reserved words), uses LIMIT and OFFSET for pagination, and has rich support for window functions, CTEs, and array operations. Function names like NOW(), COALESCE(), and string functions work as expected.
MySQL uses backtick-quoted identifiers, which is the critical difference when column names are reserved words. The GROUP BY behavior differs from Postgres in some edge cases, and MySQL 5.x lacks window functions that MySQL 8+ supports. Date and string function names also differ from Postgres in several places.
SQLite is the most permissive of the three — it accepts most SQL dialects, has flexible typing, and does not enforce foreign keys by default. However, it lacks several functions common in Postgres and MySQL (like DATE_TRUNC), which matters when the query involves date arithmetic.
Naming the correct dialect prevents the model from writing Postgres syntax for a MySQL database or using window functions in an SQLite query where they will fail.
Tips and examples
- Paste real DDL, not a paraphrase. Exact names and types let the model match your casing and avoid quoting errors.
- Include foreign keys. Join correctness improves sharply when the prompt states which columns reference which tables.
- Add one worked example. A single “Question → SQL” pair often does more for accuracy than any amount of instruction text.
- Ask for read-only output when appropriate. If the model should never write
data, say so — the prompt can forbid anything but
SELECT. - For complex schemas, consider breaking them into functional groups (users + auth, orders + products) and generating separate system prompts for each, rather than pasting a 50-table DDL that may exceed the model’s focus.