SQL INSERT Generator
Turn CSV or JSON records into ready-to-run SQL INSERT statements — escaped correctly for your database.
Paste (or upload) a batch of records and this tool writes the INSERT statements
for you: it detects CSV vs JSON, infers each column’s type, escapes quotes, backslashes and
newlines the way your specific database expects, and lets you rename columns, reorder them,
drop ones you don’t want, batch rows into multi-row statements, or emit upserts.
Change any setting and the SQL rewrites itself live.
.sql file yourself.
Your data
The file is read in your browser with the FileReader API and never uploaded — it flows into exactly the same pipeline as pasted text.
SQL options
Columns
Columns are detected automatically from the CSV header row or the JSON keys. Rename any column (it’s applied to both the column list and the generated SQL), uncheck it to drop it, reorder with the arrows, or force a type instead of letting the tool infer one.
| Include | Column name | Type | Order |
|---|
Generated SQL
Paste or upload some data above to generate INSERT statements.
Report
Nothing to report yet — add data above.
Why escaping matters
A string value in SQL is wrapped in single quotes, so a value that itself contains a single
quote — O’Brien, it’s — closes the literal early and turns
the rest of the row into code. At best you get a syntax error; at worst an attacker who
controls the data can inject statements. The standard fix is to double every single quote
(’’).
Backslashes are where dialects genuinely diverge. In MySQL, a backslash is an escape
character inside strings, so C:\new silently becomes C:new unless you
write C:\\new. In PostgreSQL, SQLite, Oracle and standard SQL, a
backslash is just a character. This tool applies each dialect’s rules automatically —
which is why the same input produces different (both correct) output depending on the
dialect you pick.
Dialect differences at a glance
| Dialect | Identifier quoting | Backslash in strings | Booleans | Upsert support here |
|---|---|---|---|---|
| MySQL / MariaDB | `backticks` | escape character — doubled | 1 / 0 | INSERT IGNORE, ON DUPLICATE KEY UPDATE |
| PostgreSQL | "double quotes" | literal character | TRUE / FALSE | ON CONFLICT … DO NOTHING / DO UPDATE |
| SQLite | "double quotes" | literal character | 1 / 0 | ON CONFLICT … DO NOTHING / DO UPDATE (3.24+) |
| SQL Server | [brackets] | literal character | 1 / 0 | — use MERGE (not generated here) |
| Oracle | "double quotes" | literal character | 1 / 0 | — use MERGE (not generated here) |
| ANSI SQL | "double quotes" | literal character | TRUE / FALSE | — |
“Auto” identifier quoting wraps a name in the dialect’s quotes only when it isn’t a plain
[A-Za-z_][A-Za-z0-9_$]* identifier or a reserved word — so order and
user-id get quoted, while price doesn’t.
Batched INSERTs and their limits
One statement per row means one round trip to the database per record. A batched multi-row
statement — INSERT INTO t (a, b) VALUES (…), (…), (…); — inserts many
rows in a single statement and is typically several times faster for bulk loads. The
practical ceiling is the server’s packet limit (max_allowed_packet in MySQL):
keep batches at 50–100 rows unless your rows are tiny. If you later move this into
application code, switch to parameterized queries — PostgreSQL caps a statement at
65,535 bind parameters — but for a one-off bulk load the generated literals are fine.
NULL vs empty string
An empty cell in a CSV is ambiguous: does it mean “no value” (NULL) or “an empty
string” (‘’)? This tool defaults to NULL, which is what most schemas want for
missing data — it keeps indexes and IS NULL filters working. If your table
distinguishes the two (for example a free-text field where “” is a meaningful answer),
untick the option in the SQL options panel. JSON is unambiguous: an explicit
"" stays an empty string and null becomes NULL.