メインコンテンツへ移動

CSV to SQL INSERT

This converter reads RFC 4180 CSV in your browser and writes SQL INSERT statements. Each cell is typed by inspection — unquoted numbers stay numbers, true and false become TRUE and FALSE, everything else is a quoted, single-quote-escaped string. Header names become double-quoted column identifiers; nothing is uploaded.

端末内で処理

このツールの画面は英語表記です。

以下の解説は英語のみでご覧いただけます。

CSV to SQL INSERT explained

CSV has no types. Everything in a spreadsheet export is text, and the database is the place that decides what a value means — which makes CSV-to-SQL the conversion where typing is done on your behalf whether you thought about it or not. This converter does it per cell and states its rules plainly: a cell that reads as a number becomes a number, true or false becomes TRUE or FALSE, an empty cell becomes NULL, and everything else is a string.

The SQL side uses the standard defences and nothing exotic: header names become double-quoted column identifiers, string values are wrapped in single quotes with embedded quotes doubled — the O''Brien form every SQL dialect reads correctly — and rows are emitted as one multi-row INSERT statement. Parsing is strict RFC 4180, so quoted fields with embedded commas or newlines survive intact, which is exactly where quick split-on-comma converters corrupt your data.

The conversion runs entirely in this browser tab. The CSV is parsed by in-page code, the SQL is assembled in memory, and no request leaves the page — the Network panel in DevTools stays empty while you work, and the site's Content-Security-Policy forbids outbound connections besides.

If your records already carry types — from an API or an export that kept them — the JSON to SQL converter takes them as given instead of inferring, with the same quoting and NULL rules.

Want the data as JSON rather than SQL? The CSV to JSON converter uses the same RFC 4180 parser and hands you typed records instead of statements.

How the conversion actually works

The engine parses your CSV by RFC 4180's actual rules — records, fields, doubled quotes inside quoted fields, CRLF or LF endings — then treats the first record as the header and every later record as one row of the INSERT. Typing is applied per cell, immediately before emission:

Two details from real spreadsheet exports are handled rather than suffered: a UTF-8 byte-order mark at the start of the file, which Excel adds by default, is stripped before parsing, and the table name you type into the tool's table field becomes the quoted identifier in the INSERT — the example below uses products.

  • Numbers: a cell matching an integer or decimal pattern is emitted bare — 42 and 24.99 become numbers. A leading zero disqualifies it, so 02134 stays a string and your postcodes survive.
  • Booleans: true or false, in any casing, becomes TRUE or FALSE.
  • Empty cells: an empty field becomes NULL. A field that is present but quoted-empty ("") stays an empty string, because RFC 4180 distinguishes the two and so does SQL.
  • Strings: everything else is single-quoted with embedded quotes doubled — O'Brien becomes 'O''Brien'.
  • Identifiers: header names are emitted as double-quoted column names, in header order.

The cell-to-literal mapping

One line per rule, so you can predict the output before you run it. Note that the empty cell and the quoted-empty cell are deliberately different rows of this table, because they are the pair people ask about most:

CSV cellSQL literalWhy
4242Integer pattern
24.9924.99Decimal pattern
trueTRUEBoolean word, any case
(empty)NULLAbsent value
02134'02134'Leading zero kept — postcode
O'Brien'O''Brien'Quote doubled per standard

What the output looks like

The worked example below is the exact pair the converter's Load sample button produces for a table named products. Three rows, each exercising one rule: the desk lamp's price is a bare decimal and its stock flag a bare TRUE; the tent row needed RFC 4180 quoting in the CSV because the product name contains a comma, and the emitted SQL doubles its apostrophe; the lantern row leaves two cells empty and both land as NULL, not as empty strings. Save the output as a .sql file and it runs as-is in psql, sqlite3 or any migration runner — the statement is complete and semicolon-terminated.

Ragged rows and other honest refusals

RFC 4180 technically permits records with fewer or more fields than the header, but SQL does not — an INSERT tuple must fill exactly the columns its statement declares. So two inputs are refused with a message naming the line, rather than padded or truncated:

  • A record whose field count differs from the header — padding with NULLs would invent values you never measured, and dropping extras would discard data you did provide.
  • Duplicate header names — two columns with the same name cannot both be quoted identifiers in one INSERT, so the converter reports the column instead of silently renaming one of them.

Frequently asked questions

Is my CSV uploaded when I convert it to SQL?

No. The parser and the SQL writer both run inside this browser tab, in JavaScript that was loaded when the page opened. There is no upload route, and the Content-Security-Policy prevents the page from connecting out. Verify it yourself in DevTools: the Network panel shows no traffic while the conversion runs, even for large files.

Which CSV dialect does the parser accept?

RFC 4180, the standard: comma-delimited fields, double-quote escaping, doubled quotes inside quoted fields, and embedded commas or newlines within quoted fields all parse correctly. Both CRLF and bare LF record endings are accepted. What it does not do is guess — semicolon- or tab-delimited files are rejected with a message, because a converter that silently swaps delimiters corrupts the columns it cannot see.

How does the type inference decide between number, boolean and string?

Per cell, against strict patterns: a field is a number only if it matches an integer or decimal literal exactly, a boolean only if it reads true or false in any casing, and NULL only if the field is empty. Everything else is emitted as a quoted string. The strictness is the point — a converter that types values like 007 aggressively will hand your database surprises.

Why did my postcode or product code stay a string?

Because it should. A code like 02134 or 007 carries information in its leading zeros, and a number has nowhere to keep them. The inference pattern refuses leading zeros on purpose, so such cells are emitted as quoted strings and the column's meaning survives the trip into the database intact.

What happens to dates in the CSV?

They arrive as quoted strings, by design. SQL date literals differ across dialects, and a converter that rewrites 2024-01-05 into a dialect-specific form is editing your data. The string reaches the database intact; a DATE column, or the database's own cast, applies the type on insert — which is the one place that decision belongs.

Can I get one INSERT statement per row instead?

The output is a single multi-row INSERT — one parse, one transaction-friendly statement, and the shape bulk-loading guides recommend. The VALUES tuples sit one per line beneath the column list, so if your tooling requires single-row statements, splitting is a mechanical edit: copy the column list and terminate each tuple with a semicolon.