creatorvalet

Convert CSV to SQL

Builds CREATE TABLE and INSERT statements from a spreadsheet export — and shows you every column type before it does.

Runs in your browser0 bytes uploaded
Waiting
Rows
Statements
Size
№ 5013waiting

Paste your CSV above, or or drop a .csv file. Nothing is uploaded — the statements are built in this tab.

The one thing a CSV to SQL converter has to get right

A spreadsheet export records no types. Every value in the file is a run of characters, and something has to decide whether 01234 is a number or a postcode before a single CREATE TABLE can be written. Get that wrong and the damage is permanent and silent: the column is declared INTEGER, the database happily stores 1234, and nobody notices until a parcel goes to the wrong town.

So the guess here is deliberately timid and, more importantly, it is shown to you before you copy anything. A column becomes a number only when every non-empty value in it is one. A leading zero disqualifies a value outright — 007 is an agent number, not seven. Forms that mean different things to different engines are treated as text on principle: 0x10, 1e5, +5 andInfinity all stay quoted rather than becoming whatever the target database happens to think they are. And every column you look at can be overridden on its own, because the mistake is nearly always about one column and not the whole file.

Quoting everything is not paranoia

Every identifier is written with the dialect's quote character, every time, whether it needs it or not. There is no cleverness deciding which names are safe, because that decision has a long list of exceptions and getting it wrong produces a file that fails halfway through. A column called order is a reserved word. One calledfirst name has a space in it. One that genuinely contains a backtick will break a MySQL statement in a way that looks like a syntax error somewhere else entirely. Quoting unconditionally makes all three uninteresting.

Apostrophes inside values are doubled rather than backslash-escaped. Both look correct in MySQL; only doubling is correct in PostgreSQL. Since a generated file has a habit of being run somewhere other than where it was made, the version that works everywhere is the only one offered.

Rows per statement is a real choice, not a preference

One INSERT per row reads beautifully in a diff and is what you want in a migration somebody has to review. A hundred rows in a single multi-rowVALUES clause runs dramatically faster, because the cost is per statement far more than per row — on a large import the difference is minutes against hours. The control is a number rather than a toggle, so you can put it wherever your case sits.

Rows that are shorter than the header get padded rather than truncated. Writing fewer values would produce a column-count error, and that error surfaces in your database rather than here, which is the worst possible place for it to appear.

When you should not use this at all

If the file and the database are in the same place, import the file. LOAD DATA INFILE, \copy, .import and every GUI client's import wizard are faster, handle far larger files, and skip this step completely. Saying so costs nothing and is the honest answer to why this whole category of tool is smaller than it looks.

Statements earn their place when the data has to travel as code. A seed file checked into a repository. A migration that gets read by a colleague before it runs. A row set destined for an environment where you cannot put a file on the disk at all. In those cases you do not want an import — you want text you can read, diff and version.

Your export never leaves the tab

The parser and the statement builder are JavaScript running in this page. There is no endpoint to upload to, which you can confirm the way you would check anyone's claim: open the network panel and drop the file. The reason it matters is what these files tend to be. A CSV on its way into a database is a customer list, an order history or a contact form export — names, addresses, email addresses, sometimes rather more. Handing that to a server-side converter is not a small favour to ask.

Nothing is refused for being large, either. Work that grows with the file runs off the main thread, so the page stays usable while a long export is being read.

Questions

How does it decide the column types?

Conservatively, and it shows you the answer before you copy anything. A column only becomes INTEGER if every non-empty value in it is a whole number, and a value with a leading zero is never treated as a number at all — 01234 is a postcode and 007 is an agent number, and INTEGER eats the zero. Anything it is unsure about becomes text, and you can change any single column afterwards without touching the others.

Which SQL dialect does it write?

Whichever you pick: standard SQL, MySQL, PostgreSQL or SQL Server. The difference is real rather than cosmetic. Identifiers are quoted with double quotes, backticks or square brackets depending on the engine, and the type names differ too — SQL Server has no BOOLEAN and no plain TEXT, so those become BIT and NVARCHAR(MAX). Everything is quoted every time, so a column called order or first name works without you having to notice.

What happens to apostrophes in my data?

They are doubled, which is the escape that works in all four dialects. The backslash form works in MySQL and breaks in PostgreSQL, so it is never used here even when the output is MySQL — a statement that only runs on one engine is a trap rather than a convenience.

Why would I generate INSERT statements instead of importing the CSV directly?

Often you should import it directly. LOAD DATA INFILE, \copy and your client's import wizard are faster and handle far bigger files. Statements are the right answer when the data has to travel as code: a seed file in a repository, a migration that gets reviewed before it runs, or a row set you need to run against an environment where the file cannot be placed.

Is my file uploaded anywhere?

No. The parsing and the statement building are JavaScript running in this tab, and there is no upload endpoint to send anything to. That matters here more than it looks: a CSV headed for a database is usually a customer list, an order export or a contact form dump, and pasting one into a server-side converter hands a stranger a copy of it.