Guide

How to review CSV to SQL INSERT statements

CSV to SQL INSERT is a code generator, not a database importer. It reads the first CSV row as columns, converts each following row into values, and gives you text to review before you run it. That makes it practical for small development fixtures and reference data, but it cannot know your schema, constraints, permissions, encodings or transaction policy.

The safest way to use it is to make its assumptions visible. Check the selected SQL dialect, table name and type-inference setting, inspect a representative row with quotes, blanks and identifier-looking values, then run generated SQL only in an environment you can verify. For production-scale loading, use the database’s native bulk loader or parameterized application code instead.

Open the CSV to SQL INSERT

Use this when


  • Seeding a local development database from a small CSV export
  • Creating reviewable fixture INSERT statements for a migration or test
  • Moving a spreadsheet of reference rows into a known table
  • Inspecting how blank cells and quoted text will be represented in SQL
  • Preparing a small, manually reviewed one-off data load

Start with the exact CSV shape


The first parsed row supplies the INSERT column list. Every later row supplies values in that same position order. The generator does not query a database, so a header named `full name` is quoted as an identifier when that option is on; it does not prove that a column with that name exists or that its type accepts the generated literal.

CSV parsing handles quoted commas, doubled quotes and quoted line breaks before SQL generation. Headers are trimmed, blanks become positional column_N names, and repeated names gain suffixes. A pre-existing suffix can still collide: id,id,id_2 becomes id,id_2,id_2. The generator preserves that duplicate column list rather than validating a schema. Missing cells become blank input; extra cells beyond header width are discarded without a dedicated ragged-row warning here. Validate row widths and headers before generating SQL.

The table name is one identifier string, not a SQL expression. With identifier quoting enabled, a value such as `public.users` is quoted as one identifier (`"public.users"` in PostgreSQL-style quoting), not split into schema `public` and table `users`. Use the actual table name expected by your database or generate separate SQL after choosing the correct connection and schema. The processor defaults to my_table and one INSERT per row; a blank trimmed table name also falls back to my_table.

id,name,email
1,Alice,alice@example.com
2,O'Brien,
This uses `id`, `name` and `email` as column identifiers and supplies two data rows. The apostrophe and blank cell are the useful review cases.

Read identifier quoting as dialect syntax only


The dialect option changes identifier quotes only: PostgreSQL and the generic SQL form use double quotes, MySQL and MariaDB use backticks, and Transact-SQL uses square brackets. These quotes protect identifier spelling and reserved words; they do not translate data types, add a schema, validate a table, or make the emitted statement portable to every database advertised by the formatter.

Quote table and column names unless you deliberately control simple identifiers and know the target dialect’s folding rules. Quoting preserves the header spelling, which can be useful for a mixed-case or reserved header, but it also means a PostgreSQL header `UserId` refers exactly to `UserId`, not its unquoted lowercase equivalent.

Do not use a table-name field to add `WHERE`, a schema expression, a database name or SQL punctuation. Identifier quoting makes that text a literal identifier, which is safer than treating it as executable SQL but may produce an invalid identifier. Connection selection and schema qualification belong in your database workflow, not in this one input.

Selected dialectQuoted `order` columnWhat changes
PostgreSQL / generic SQL`"order"`Double-quoted identifier
MySQL / MariaDB``order``Backtick identifier
Transact-SQL`[order]`Square-bracket identifier

Type inference changes SQL literals


With type inference on, an empty CSV cell becomes SQL `NULL`; decimal or integer text matching the generator’s numeric pattern becomes an unquoted number; and lowercase `true` or `false` becomes the SQL literals `TRUE` or `FALSE`. Other cells are string literals. This is convenient when the CSV really represents those types and dangerous when a code, postcode or account number only looks numeric.

A string cell whose text is exactly `NULL` in any capitalization is emitted as the unquoted SQL `NULL`, even with type inference off and even if the CSV field was quoted. This special case happens in the SQL literal renderer after inference. There is no option to retain that exact word as text: use a reviewed manual edit or a parameterized import when it is legitimate data. Padded text such as ` NULL ` is not the same case and remains a quoted string.

With inference off, raw CSV fields stay strings, including blank fields. The SQL literal renderer then emits an empty field as `''`, not `NULL`; text `true` is quoted rather than becoming a boolean. The exact NULL-text exception still applies. Prefer this setting for identifiers and import data whose schema types you will explicitly validate later.

This generator has a different numeric rule from CSV to JSON. It accepts signed integers and decimals without leading zeros, but not exponent notation, leading plus signs or padded numbers. Lowercase true and false are recognized without trimming; uppercase TRUE is text. Leading-zero 007 remains a string, but 9007199254740993 matches the number rule and rounds to 9007199254740992 because there is no safe-integer guard. Extremely large matches can become non-finite and render as NULL. Disable inference for exact IDs or amounts and verify the quoted output.

INSERT INTO "users" ("id", "name", "email") VALUES (1, 'Alice', 'alice@example.com');
INSERT INTO "users" ("id", "name", "email") VALUES (2, 'O''Brien', NULL);
With inference on, `1` is numeric, `O'Brien` has a doubled quote, and the blank email is `NULL`.
CSV text with inference onGenerated literalReview question
blank cell`NULL`Is absence really null?
exact `NULL`, `null`, or `Null``NULL`This special case applies even when inference is off
`true` / `false``TRUE` / `FALSE`Does the target dialect and column accept it?
`007`'007'Leading-zero text is preserved by this numeric pattern

Escaping is not the same as a database security boundary


String literals are escaped by doubling single quotes, the standard SQL convention: `O'Brien` becomes `'O''Brien'`. The output is intentionally text you can read and review; it is not an API for constructing queries at runtime. Runtime code should use the parameter binding facility provided by its database driver, even if this generated example looks correctly escaped.

The implementation does not add dialect-specific casts, binary literal forms, date constructors, encoding declarations or schema checks. It has no knowledge of triggers, generated columns, defaults, foreign keys or permissions. A statement that looks syntactically plausible can still fail or write the wrong kind of data when those database rules are applied.

MySQL is the important escaping caveat. The generated form relies on doubled single quotes. MySQL can also treat backslashes as escapes unless its `NO_BACKSLASH_ESCAPES` mode is enabled, so a backslash-containing value needs testing in the actual server mode. Do not assume a generated literal has identical backslash semantics across MySQL, PostgreSQL and SQL Server.

name,note
O'Brien,C:\temp\new
Review this in the selected target database. The quote is doubled; the backslashes need particular care in MySQL because server SQL mode affects their interpretation.

Use a small-load review checklist


Generate a few rows first, preferably including every awkward value shape you expect. Compare the output column order with `DESCRIBE`, `\d`, migration source or another authoritative schema view. Confirm whether blanks are nulls, whether leading-zero values need inference disabled, and whether literal `NULL` should remain text.

Run the approved SQL in a disposable transaction or development database, then query the inserted rows back using the target database. This catches dialect behavior that static generation cannot know, including timestamp conversion, constraint failures and collation. Keep the original CSV and the reviewed generated SQL together so the operation is reproducible.

For large data, do not turn one statement per row into a deployment mechanism. The optional multi-row form is more compact, but servers impose statement, packet and transaction limits. Native facilities such as PostgreSQL COPY, MySQL LOAD DATA and SQL Server bulk tooling are designed for volume and offer better failure reporting.

  • Check the header names and table name against the target schema.
  • Select the database dialect for identifier quotes only.
  • Review blanks, `NULL`, booleans, leading-zero values and apostrophes.
  • Test a representative batch in a disposable environment.
  • Use parameterized runtime queries or a native bulk loader for real applications and large loads.

PostgreSQL INSERT documentation — Use the documentation for your actual database as the authority for syntax, types and import limits.

Common problems


Each of these is something that actually happens, with the cause rather than a generic suggestion to check your input.

The statement names a table called `public.users` instead of using schema `public`

Cause
The generator treats the table-name field as one identifier and quotes it as one identifier.
Fix
Choose the target schema through your connection or database workflow; do not expect the field to parse schema-qualified expressions.

A blank CSV cell became NULL but the column needs an empty string

Cause
Type inference is on, and empty input is deliberately represented as null.
Fix
Turn inference off for text-preserving output, then review the generated `''` literals.

The text NULL was not inserted as four characters

Cause
The literal renderer treats an exact case-insensitive NULL cell as the SQL NULL literal, even when inference is off.
Fix
Review and manually adjust this exceptional value, or use a parameterized import; the generator has no option for an exact quoted NULL string.

A backslash-containing value behaves differently in MySQL

Cause
MySQL server SQL mode can give backslashes escape semantics, unlike the doubled-quote rule used for apostrophes.
Fix
Test against the target MySQL mode, especially when `NO_BACKSLASH_ESCAPES` is not set; use bound parameters for application input.

Questions


Does selecting a dialect make all SQL portable?
No. The option changes identifier quoting syntax only. It does not infer schema names, validate types, or adapt INSERT behavior, limits or string semantics beyond the generated identifier delimiters.
Why are booleans TRUE and FALSE?
With inference on, lowercase CSV `true` and `false` are converted to JavaScript booleans, and the SQL renderer emits `TRUE` and `FALSE`. Verify that representation against your actual target database and column.
Are generated INSERT statements safe for user input?
They are reviewable generated text, not a runtime query API. Single quotes are doubled, but application code should always use database-driver parameter binding for untrusted input.
Can I use this for hundreds of thousands of rows?
It is intended for small reviewed sets. Use your database native bulk loader for large loads; it is faster and has database-specific error handling.