Advertisement
Guide
About the SQL INSERT Generator
Getting a spreadsheet of data into a database usually means either an import wizard you do not trust or hand-writing a hundred INSERT statements. This generates them for you, with values escaped properly so a name like O'Brien cannot break the statement.
Useful for seed data, test fixtures, and one-off migrations.
Escaping is the whole point
The reason not to build INSERT statements with string concatenation is that a single apostrophe ends the string literal early and everything after it is parsed as SQL. This tool doubles apostrophes (''), which every dialect understands, and handles the differences: MySQL also treats a backslash as an escape, so C:\new would silently become a newline unless the backslash is doubled; SQL Server needs an N'…' prefix to keep characters outside its code page; and Oracle's SQL*Plus treats & as a variable unless SET DEFINE OFF is set. Generated SQL is for data you control — for user input in a running application, always use parameterised queries instead.
One statement per row, or batched
A batched insert — one INSERT with many VALUES tuples — is dramatically faster, because the database parses and plans once instead of once per row. One statement per row is easier to read and edit, and means a single bad row does not fail the whole batch. Batches of 100 to 1,000 are a reasonable default; very large batches can exceed a server's maximum packet size, and SQL Server refuses more than 1,000 rows in one VALUES list, so batches are capped there. Oracle gets INSERT ALL, its form of a multi-row insert. Tick “Transaction” to make the whole script succeed or fail as one.
How types are decided
Values that look like integers or decimals are written unquoted, true and false become booleans, and empty cells become NULL if you enable that. Numbers with a leading zero — zip codes, phone numbers, 007 — stay text, and so does a whole column once any value in it is text, so a database never turns '02134' into 2134. Integers too long for JavaScript to hold exactly stay text, and decimals with more digits than a double keeps are written digit for digit. For CREATE TABLE, dates, timestamps (with or without a time zone), UUIDs and JSON get proper column types, and DECIMAL is sized to fit the data.
Dialect differences that matter
PostgreSQL and SQLite quote identifiers with double quotes, MySQL with backticks, SQL Server with square brackets. PostgreSQL has real TRUE and FALSE literals; MySQL and SQL Server use 1 and 0. Upserts are ON CONFLICT … DO UPDATE in PostgreSQL and SQLite, ON DUPLICATE KEY UPDATE in MySQL, and MERGE in SQL Server and Oracle. MySQL's DATETIME has no time zone, so timestamps with an offset are converted to UTC; Oracle gets DATE '…' and TIMESTAMP '…' literals because it does not read ISO strings as dates on its own.
How to use it
- 1Paste CSV (or cells copied from Excel) with a header row, a JSON array, or open a file.
- 2Set the table name — schema.table works — and pick your database.
- 3Choose batching, what happens to existing rows, and which columns to keep.
- 4Copy the SQL or download it as a .sql file.
Frequently asked questions
How are apostrophes handled?
They are doubled, which is the standard SQL escape. A value like O’Brien becomes 'O''Brien' and runs correctly on every dialect. For MySQL, backslashes are doubled too.
Can it generate upserts?
Yes. Set “If the row exists” to “Update it” and choose the key column. You get ON CONFLICT … DO UPDATE for PostgreSQL and SQLite, ON DUPLICATE KEY UPDATE for MySQL, and MERGE for SQL Server and Oracle. “Skip it” inserts only new rows.
Why did my zip code stay in quotes?
Because 02134 is not the number 2134. Values with leading zeros, and every value in a column that contains text, are written as strings so nothing is lost.
Should I use batched or single inserts?
Batched is much faster for large imports because the database parses once. Use one per row when you want readable, individually editable statements, or need a bad row to fail on its own.
Can it create the table too?
Yes. Turn on CREATE TABLE and column types are inferred from the data — including dates, timestamps, UUIDs and JSON — with the key column as the primary key. Treat it as a starting point; it cannot infer indexes or other constraints.
Why is my long ID quoted as a string?
Because JavaScript loses precision on integers above roughly 9 quadrillion. Quoting keeps the exact digits rather than silently rounding them.
Is my data uploaded?
No. Parsing and generation both happen in your browser.
