Open or paste a CSV file, pick the Database and Statement, and the script appears next to the options. By default it is a PostgreSQL transaction with a CREATE TABLE IF NOT EXISTS of TEXT columns and INSERTs of 100 rows each, so 00412 stays '00412'. Choose Detect numbers and true/false when the table should get numeric, boolean and DATE columns. The file is converted in your browser and never uploaded.
How to convert CSV to SQL
- Open a
.csv,.tsvor.txtfile, drop it on the tool, or paste rows. The delimiter is detected; set it, the header row or a legacy encoding such as Windows-1252 under Import settings. - Choose the Database: PostgreSQL, MySQL / MariaDB, SQLite or SQL Server. Check the Table name, which starts as the file name with spaces and punctuation turned into underscores (
sales report.csvbecomessales_report). - Choose the Statement and, for UPSERT, UPDATE or DELETE, tick the Key columns that identify a row.
- Review the preview, then select Copy or download the
.sqlfile and run it with your database client, for examplepsql -f data.sql.
To script many files with the same settings, choose Batch: convert several files. Each file is converted in turn and the scripts download together as one ZIP.
Statements and options
| INSERT | Multi-row INSERT INTO … VALUES statements. Rows per INSERT sets how many rows share one statement (1–1,000, default 100); SQL Server rejects more than 1,000. |
|---|---|
| UPSERT (insert or update) | One statement per row that inserts it or updates the existing row with the same key: ON CONFLICT (…) DO UPDATE SET … = excluded.… in PostgreSQL and SQLite, ON DUPLICATE KEY UPDATE in MySQL, and MERGE in SQL Server. The target table needs a primary key or unique index on the key columns. |
| UPDATE | UPDATE … SET … WHERE key = … for every row; key columns are not changed. If every column is a key, there is nothing to update and no statements are written. |
| DELETE | DELETE FROM … WHERE key = … for every row. An empty key value becomes IS NULL. |
| Key columns | Required for UPSERT, UPDATE and DELETE; the tool will not write one of those statements without a WHERE key. With Add CREATE TABLE, key columns become NOT NULL and the PRIMARY KEY. |
| Add CREATE TABLE | On by default. Writes CREATE TABLE IF NOT EXISTS (plain CREATE TABLE for SQL Server, or after a DROP). |
| Add DROP TABLE IF EXISTS first | Replaces an existing table of the same name. Off by default; the old table and its data are lost when the script runs. |
| Wrap in a transaction | On by default: BEGIN; … COMMIT; (START TRANSACTION; in MySQL, BEGIN TRANSACTION; in SQL Server). |
| Write empty cells as NULL | On by default. Turn it off to write empty cells as '' instead. |
Column types and quoting
With Keep every value as text (the default) every column is TEXT (NVARCHAR(MAX) in SQL Server) and every value is a quoted string literal, so leading zeros, long IDs and odd dates load unchanged.
With Detect numbers and true/false, a column gets a type only when every non-empty value fits it:
| Whole numbers | INTEGER, or BIGINT when a value has more than 9 digits. Values are written unquoted. Numbers with leading zeros or beyond 9,007,199,254,740,991 keep the column as text. |
|---|---|
| Decimals (at most 15 significant digits) | NUMERIC in PostgreSQL, DECIMAL(p,s) sized from the data in MySQL and SQL Server, REAL in SQLite. A decimal comma such as 1,5 keeps the column as text. |
| true / false (any letter case) | BOOLEAN with TRUE/FALSE in PostgreSQL and MySQL, BIT with 1/0 in SQL Server, INTEGER with 1/0 in SQLite. |
| Dates as YYYY-MM-DD | DATE, with quoted values such as '2026-03-01'; TEXT in SQLite. Date-times and other date formats stay text. |
- Table and column names are quoted exactly as written, so spaces, reserved words and non-Latin names work:
"order date"in PostgreSQL and SQLite, `order datein MySQL,[order date]` in SQL Server. Embedded quote characters are doubled. - In values, a single quote is doubled (
O'Brienbecomes'O''Brien'). For MySQL, backslashes are doubled too, because MySQL treats\as an escape by default. SQL Server literals get theNprefix so Unicode text is kept. - Line breaks inside a quoted CSV value stay inside the SQL string literal.
- NUL characters can't be stored by most databases; they are removed and the tool reports how many.
When the SQL script fails to run
- The script is all one column. The delimiter was guessed wrong; set it under Import settings and open the file again.
- A number column came out as TEXT. At least one value isn't a plain number, for example
12 kg,1,5or007. Find it in the CSV viewer or fix the column with Clean CSV data. - The UPSERT fails with a missing constraint.
ON CONFLICTandON DUPLICATE KEYonly work when the target table has a primary key or unique index on the key columns. Add the index to the existing table, or let Add CREATE TABLE create the key. - MySQL or SQL Server rejects the PRIMARY KEY. A key column that stays text is created as
TEXT(MySQL/MariaDB) orNVARCHAR(MAX)(SQL Server), and neither database can index those types in full. Create the table yourself with aVARCHARkey, then turn off Add CREATE TABLE. - SQL Server reports that the table already exists. SQL Server scripts use plain
CREATE TABLE. Turn off Add CREATE TABLE to load into the existing table, or turn on Add DROP TABLE IF EXISTS first to replace it. - The script stops partway through. The database error names the failing statement; the usual causes are a duplicate key or a value that doesn't fit a column type of an existing table. Check the file with Validate CSV and run the script again.
Large files and limits
Files up to 25 MB, 100,000 rows or 2 million cells open with a live preview. Larger files are converted in streaming mode: the preview shows the first 200 rows, the file is read twice in chunks (once to learn the column types and widths, once to write the script), and the download covers every row. A single script is capped at 4 GB.
Conversion runs in a background worker in this tab, so the page stays responsive and Cancel stops it. The CSV is never sent to a server. To get a ready-made database file instead of a script, use CSV to SQLite.
Example: a customer list as PostgreSQL INSERTs
A customer list with a leading-zero ID, a name containing an apostrophe and a comma, and an empty plan, converted with the default settings and the table name customers. With Detect numbers and true/false, signup_date becomes DATE, monthly_fee becomes NUMERIC with unquoted 29.00, and active becomes BOOLEAN with TRUE/FALSE, while customer_id stays TEXT.
customer_id,name,signup_date,plan,monthly_fee,active 00412,"O'Brien, Kate",2026-03-01,pro,29.00,true 00413,Luis Ortega,2026-03-04,,0,false
BEGIN;
CREATE TABLE IF NOT EXISTS "customers" (
"customer_id" TEXT,
"name" TEXT,
"signup_date" TEXT,
"plan" TEXT,
"monthly_fee" TEXT,
"active" TEXT
);
INSERT INTO "customers" ("customer_id", "name", "signup_date", "plan", "monthly_fee", "active") VALUES
('00412', 'O''Brien, Kate', '2026-03-01', 'pro', '29.00', 'true'),
('00413', 'Luis Ortega', '2026-03-04', NULL, '0', 'false');
COMMIT;Questions and answers
Why is every column TEXT by default?
CSV has no types, and guessing wrong loses data: an ID like 00412 stored as an integer becomes 412. Text loads exactly what the file says. Choose Detect numbers and true/false when you want numeric, boolean and DATE columns.
Which databases can run the script?
PostgreSQL, MySQL and MariaDB, SQLite, and SQL Server, each with its own identifier quoting, string escaping, boolean values and upsert syntax. Pick the matching Database before you download; a script written for one is not portable to the others.
Can it generate COPY or LOAD DATA commands instead of INSERTs?
No. The script uses standard INSERT, UPSERT, UPDATE or DELETE statements. For very large loads, consider your database's own bulk loader, such as COPY in PostgreSQL or LOAD DATA in MySQL, reading the CSV directly.