A dump is data wearing SQL syntax
An INSERT statement already holds a table: column names in the parentheses after the table name, one row per value tuple after VALUES. Getting to CSV is a matter of reading those two lists correctly and re-quoting the values under CSV rules instead of SQL rules. The whole job sounds like a search and replace until the first row contains an address with a comma in it, at which point the naive version quietly splits one row into two.
Why splitting on commas fails
SQL and CSV both use commas as separators and both use quotes to protect commas inside a field. They disagree on almost everything else, and each disagreement is a row that lands in the wrong column.
| Situation | SQL writes it as | CSV needs |
|---|---|---|
| Text with a comma | 'Berlin, DE' | "Berlin, DE" |
| Apostrophe in text | 'O''Brien' or 'O\'Brien' | O'Brien with no escaping at all |
| Double quote in text | '27" monitor' | "27"" monitor" |
| Missing value | NULL | An empty field, or a token you choose |
| Line break in text | 'line one\nline two' | A real newline inside a quoted field |
| Function result | NOW() | The literal text, since nothing evaluates it |
The parser here reads the VALUES section character by character rather than matching a regular expression against it. It tracks whether it sits inside a quoted string, counts nested parentheses so a CONCAT(a, b) argument list stays one field, and treats a doubled quote as an escaped quote rather than the end of the string. That is the difference between a row surviving and a row shifting one column to the left for the rest of the file.
INSERT INTO shops (id, name, note) VALUES
(1, 'Bao & Co, Wan Chai', NULL),(2, 'O''Brien''s', 'has a 27" sign');id,name,note
1,"Bao & Co, Wan Chai",2,O'Brien's,"has a 27"" sign"Three rewrites happened in those two rows. The comma inside a shop name pulled quotes around that field. The doubled SQL apostrophe collapsed back to one and needed no CSV quoting at all. The inch mark got doubled, because a quote inside a quoted CSV field is written twice. Field two on row two is quoted for the inch mark, field two on row one for the comma, and nothing else is quoted, which is what minimal quoting means.
Statements the parser reads
Dumps come out of a dozen tools and none of them agree on formatting. These forms are all accepted.
- Multi-row inserts. One INSERT with forty tuples after VALUES is read as forty rows. mysqldump writes this way by default.
- Repeated single-row inserts. Forty separate INSERT statements against the same table are merged into one CSV, since they share a column list.
- Quoted identifiers. Backticks from MySQL, double quotes from Postgres, square brackets from SQL Server. All three are stripped off table and column names.
- Schema prefixes.
public.ordersordbo.Orderskeeps its full name in the table picker so two schemas holding a table of the same name stay apart. - Dialect keywords.
INSERT IGNORE,INSERT OR REPLACEandREPLACE INTOare treated as ordinary inserts. - Comments. Line comments starting with two dashes and block comments are removed first, unless the dashes sit inside a string, where they are left alone.
- No column list.
INSERT INTO t VALUES (1, 2)carries no names, so the header becomescolumn_1,column_2and a note tells you the names came from nowhere.
Several tables in one file
A real dump holds users, then orders, then line items, each with a different column count. Flattening all of that into one CSV produces a file no spreadsheet will read. Each table gets its own output instead, and the picker at the top right switches between them. Row counts sit next to each name, so a table that came through with two rows when you expected two thousand is visible before you download anything.
Rows are keyed to their table by name, not by position, so an interleaved dump that returns to the users table halfway down still collects every user row into one CSV. The download button names the file after the table you are looking at.
When two INSERT statements target the same table with different column lists, the first list wins and the mismatch is reported in the notes. A row with fewer values than the header is padded with empty fields on the right. A row with more values is cut. Both cases increment the patched counter, and a patched count above zero is worth reading the notes over, since it usually points at a column list that changed partway through the file.
Choosing a separator
Comma is the default and the right answer for anything you feed to a script or a database import. The other three exist because spreadsheets have opinions.
- Semicolon is what Excel expects on machines with a European locale, where the comma is the decimal mark. Open a comma file there and every row lands in a single column.
- Tab avoids the escaping question almost entirely, since tabs rarely appear in stored text. Paste tab output straight into a sheet and the columns split on their own.
- Pipe is the fallback for text that contains commas, semicolons and tabs all at once, common in exported log or note fields.
Whichever you pick, the escaping follows it. Switch to semicolon and a value containing a semicolon gets quoted while a value containing a comma stops being quoted. The rule is the same in every case: quote when the field holds the separator, a double quote, a carriage return or a newline.
NULL is not an empty string
CSV has no way to say a value is absent. It has empty fields, and an empty field means the empty string as easily as it means missing. That ambiguity is why three options sit above the editors.
| Option | Written as | Pick it when |
|---|---|---|
| Blank | Nothing between the separators | The target is a spreadsheet, where an empty cell reads naturally |
| NULL | The four letters NULL | You are eyeballing the file, or reloading it somewhere that maps the word back |
\N | Backslash then capital N | The file goes into LOAD DATA INFILE or a Postgres COPY, which both read that token as null |
One warning about the NULL word option. A row that stores the literal text 'NULL' as a string becomes indistinguishable from a genuine null the moment it lands in the file. If your data has string values spelling out NULL, take the blank option or the backslash token instead.
Getting the file into Excel without mangling it
Excel treats a CSV as a set of hints and applies its own conversions on open. Four of them bite regularly.
- Leading zeros vanish. A postcode of
02134becomes 2134, because the column was read as a number. Import through Data then From Text rather than double clicking the file, and mark that column as text. - Long numbers turn into scientific notation. Anything past fifteen digits, credit card numbers and large IDs included, loses precision permanently on save. Same fix.
- Dates get reformatted. A stored
2026-03-14can come back out as 14/03/2026 depending on your locale. The value in the file is correct, the display is not, and saving over it writes the display back. - Accented text arrives as mojibake. The download here starts with a UTF-8 byte order mark for exactly this reason, which is what tells Excel to read the file as UTF-8. If you copy the text out of the panel instead of downloading, that mark is not there.
The CRLF option matters for the same audience. Windows tooling and the CSV specification both want carriage return plus line feed at the end of a row. Everything on Unix is fine with a bare line feed. Turn CRLF on if the file is headed for Excel or an older Windows import, leave it off for anything else.
What this converter does not do
- No SELECT, UPDATE or DDL. Only INSERT and REPLACE statements carry rows. A
CREATE TABLEblock is skipped, which means column types, defaults and constraints never reach the CSV, because CSV has nowhere to put them. - No expression evaluation.
NOW(),UUID()and1 + 1arrive as text, since evaluating them would need the database that was going to run the statement. - No
INSERT ... SELECT. Those statements carry a query rather than literal values, so there is nothing to read without executing it. - No hex or binary decoding. A blob written as
0x89504E47stays as that string. Decoding it would produce bytes no CSV field wants. - No type inference. Every value goes out as text and the receiving program decides what it is. That is the whole reason leading zeros survive the file and then die in Excel.
- Large dumps slow the tab. Parsing runs on the main thread in your browser. A few megabytes is comfortable. A half gigabyte production dump is a job for
mysqldump --tabor aCOPY TOon the server, which stream straight to CSV without a browser in the middle.
Nothing you paste is uploaded. The parser, the formatter and the download all run inside this page, so a dump holding customer rows never leaves your machine. Load the page once, cut your connection, and it keeps converting.
