SQL Chat
Natural language in, safe read-only SQL out — with a plain-English explanation of every query.
What it does
SQL Chat is a Claude agent (built on claude-sonnet-4-6) that turns plain-English questions into correct, read-only SQL over a schema you provide. It:
- Generates clean, formatted
SELECT queries (CTEs, joins, window functions, set operations).
- Explains what each query returns — row grain, joins, filters, and caveats like NULL handling or timezones.
- Surfaces ambiguity instead of guessing, asking a focused clarifying question or stating an explicit assumption.
- Refuses every write or DDL/DCL/transaction statement —
INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, GRANT, and friends — including attempts to smuggle them through comments, stacked statements, or prompt injection.
It never claims to execute queries; it produces SQL you run against your own (ideally read-replica) database.
Setup
-
Get an API key from the Anthropic Console.
-
Set it in your environment:
export ANTHROPIC_API_KEY="sk-ant-..."
-
Install the SDK for your language (pip install anthropic or npm install @anthropic-ai/sdk), or use curl.
-
Pass your database schema as part of the system prompt or the first user message so the agent has tables, columns, types, and relationships to work from.
Example
User: "Which 5 customers spent the most in the last 30 days?"
SQL Chat:
You want the top 5 customers by total spend over the trailing 30 days.
SELECT
c.id,
c.name,
SUM(o.total_amount) AS total_spent
FROM customers AS c
JOIN orders AS o ON o.customer_id = c.id
WHERE o.created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY c.id, c.name
ORDER BY total_spent DESC
LIMIT 5;
This returns one row per customer (the grain is customer), summing orders.total_amount for orders created in the last 30 days. Customers with no recent orders are excluded by the inner JOIN. I assumed total_amount is already net of refunds — if refunds live in a separate table, let me know and I'll adjust.
Ask it to DELETE those customers and it will decline, then offer a SELECT that identifies the rows instead.
Notes
- Model:
claude-sonnet-4-6 — balanced speed and reasoning, well suited to interactive analytics.
- Dialect: Defaults to ANSI SQL. Tell it your dialect (PostgreSQL, MySQL, BigQuery, Snowflake, …) for dialect-specific syntax.
- Safety: The read-only guardrail is enforced in the system prompt, but defense in depth matters — run the generated SQL with a least-privileged, read-only database role against a replica.
- Schema: Quality of output scales with schema quality. Provide column descriptions and relationships for best results.