Data

CSV to SQL INSERT, with the CREATE TABLE written for you

Paste CSV, JSON or XML, or drop an Excel file, and get SQL for MySQL, PostgreSQL, SQL Server, Oracle or SQLite. Or convert to JSON, YAML, Markdown and more.

Zero uploads · all in your browser

Parsing and generation happen inside your browser: what you paste here never travels to a server, not even the Excel file.

Why “nothing is uploaded” matters here

What people paste into a CSV-to-SQL converter is almost never toy data: it is a production export — a customer list, an orders table with real amounts. Running that through a site that uploads it means handing personal data to a third party you have not audited and that almost certainly is not in your processing records. Here there is nowhere to upload it to: the parser and the generator are JavaScript running in your tab. Load the page, kill your Wi-Fi and see for yourself.

How it works, in 3 steps

  1. Paste or drop your data

    CSV, TSV, JSON, XML, or an .xlsx dragged onto the panel. The format is detected automatically, and so is the delimiter — commas or semicolons, it does not matter.

  2. Pick the output

    SQL, JSON, JSON Lines, XML, YAML, Markdown, HTML or CSV. Choose SQL and the engine, table name, CREATE TABLE and INSERT style options appear.

  3. Copy or download

    The right panel updates as you type. Check the types it inferred, adjust what you need and copy to the clipboard or download the file.

Try it without hunting for a file

The three sample data buttons above the tool load a realistic dataset in one click — each one packed with exactly what breaks most converters:

CSV to SQL INSERT without hand-writing the CREATE TABLE

The tedious part of loading a CSV into a database was never the INSERTs. It is deciding each column's type, remembering how the engine of the day quotes identifiers, and getting the quote escaping right. That is exactly what this does. It walks each column in full, looks at every value, and decides: all whole numbers gives INT; any decimal gives DECIMAL with the scale required; true/false or yes/no gives the engine's boolean; anything that parses as a date gives DATE or DATETIME; everything else is text.

Two details most converters get wrong. First, a column containing any blank value becomes NULL; one with none becomes NOT NULL. Second, the VARCHAR length is rounded up — 10, 20, 50, 100, 255 — rather than fitted to the exact character count of the longest sampled value. A VARCHAR(11) derived from three example rows explodes the moment a slightly longer name arrives, and that is worse than generating nothing.

Even so, treat it for what it is: a very advanced starting point, not a finished schema. Review the CREATE TABLE, add the primary key, the indexes and the foreign keys, and size the lengths to what you actually know about the domain before you run it.

The engine differences that eat your afternoon

Every engine speaks SQL right up until you look closely. All five are handled:

  • MySQL quotes with backticks and — watch out — interprets backslashes inside string literals, so they have to be doubled. An unescaped C:\path leaves your string mangled.
  • PostgreSQL quotes with double quotes and has a real BOOLEAN, so booleans come out as TRUE/FALSE rather than ones and zeroes.
  • SQL Server quotes with brackets and prefixes strings with N so accented characters reach an NVARCHAR column intact.
  • Oracle upper-cases identifiers, uses VARCHAR2 and NUMBER, and wraps dates in TO_DATE with an explicit mask. It also has no multi-row VALUES, so INSERT ALL … SELECT * FROM dual is generated instead.
  • SQLite has type affinity rather than strict types, so everything resolves to INTEGER, REAL and TEXT.

In all five, single quotes get doubled. An O'Brien in your data comes out as 'O''Brien' and lands cleanly.

JSON to CSV converter, and back again

The other direction is just as direct: paste an array of objects and switch the output to CSV. If the JSON is not an array but an object wrapping one — the classic API response shaped like {"data": [...]} — the first array found is used. Keys missing from some objects still become columns, filled with blanks where absent, so you do not silently lose fields.

About nested values, honestly: if a property is itself an object or an array, it is serialised as JSON inside the cell. A table is flat and JSON need not be; flattening automatically, by guesswork, produces worse results than leaving it visible.

Excel to SQL script without installing anything

Drag the .xlsx onto the panel and the first sheet is read. As everywhere else, the engine that understands the format downloads the first time it is needed, never on page load. The contents land in the input panel as CSV, so you can review and fix them before generating anything, rather than converting blind.

One genuinely useful warning: Excel loves to reformat. If your code column has leading zeros and they reach this page, the converter keeps them and types the column as text. But Excel has very probably eaten them before the file ever got here, and what was lost at the source cannot be recovered here: format that column as text in Excel, or export to CSV straight from whatever produced the data.

The limits, stated before they bite

Around 50,000 rows is comfortable; past that it depends on your machine's memory. Above 400 rows the right panel shows a preview only — painting a hundred thousand lines into a textarea helps nobody and jams the browser — but copying or downloading generates the complete set. Excel files read the first sheet. Nested JSON values are serialised, not flattened. And type inference only sees the data you gave it: if your sample is 10 rows, it cannot know what is in the other 10,000.

Frequently asked questions

How are column types inferred?

By reading the whole column. Every non-empty value a whole number gives INT — or BIGINT if any exceeds 2,147,483,647. Decimals give DECIMAL with the required scale. true/false, yes/no and friends give the engine's boolean. ISO or slashed dates (12/25/2024) give DATE or DATETIME: month/day versus day/month is worked out from the whole column, and when no value settles it, month/day is assumed and shown as “assumed”. A digits-only column with leading zeros, like a ZIP code, stays text so the zeros survive, and so does a 1,234 that could be a decimal or a thousand. Anything else is text.

A column with any blank becomes NULL; one with none becomes NOT NULL. The detected types are listed below the panel so you can check them before copying.

Why is the VARCHAR bigger than my longest value?

On purpose. The length is measured on what you pasted, which is a sample, so it is rounded up to sensible sizes (10, 20, 50, 100, 255, 500…).

A VARCHAR sized to the exact character count breaks on the first real record that runs a little longer. Even so, review the CREATE TABLE and size it to what you know about your domain before running it.

Does it escape quotes and awkward characters properly?

Yes, following each engine's rules. Single quotes are doubled in all five. MySQL additionally gets its backslashes doubled, because it interprets escape sequences inside literals. SQL Server strings carry the N prefix so accents survive.

Identifiers are wrapped in brackets, backticks or double quotes depending on the engine, and Oracle dates are wrapped in TO_DATE with an explicit mask.

What is the difference between single and multi-row INSERTs?

One per row is easier to read and to debug: when something fails you know exactly which line. Multi-row packs several rows into one INSERT and is far faster on big loads, because it means fewer round trips.

Oracle has no equivalent syntax, so INSERT ALL … SELECT * FROM dual is generated instead.

What does cleaning column names do?

It turns headers like “Full Name” or “Price (€)” into full_name and price: strips accents, replaces spaces and symbols with underscores, and prefixes names starting with a digit. You can switch it off to keep the original names, quoted.

Is my data uploaded anywhere?

No. Parsing and generation are JavaScript running in your tab. No request carries the content to a server, not even for Excel. Load the page, disconnect from the internet and check: it keeps working.

How many rows can it handle?

Around 50,000 comfortably. Above 400 the right panel shows a preview only, to keep things responsive, but copying or downloading generates all of them. Your machine's memory is the real ceiling.

What if my CSV uses semicolons instead of commas?

It is detected automatically. Comma, semicolon, tab and pipe are each tried against the first few lines, ignoring any that sit inside quotes, and whichever yields a coherent table wins. This is the standard case for CSV exported from a European Excel.

Related guide

Related tools