Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

CSV to SQL Converter

Typed CREATE TABLE and batched INSERTs, upserts or bulk-load scripts for six databases.

Data No upload Works offline Free, no sign-up

Database and table

Database
More options: names, text, empty cells

Comma-separated, e.g. NULL, \N, N/A

Columns

Use Column name Type NOT NULL Examples

SQL

Next steps

About the CSV to SQL Converter

Paste a CSV (or open a CSV, TSV, Excel or JSON file) and get SQL you can run: a CREATE TABLE with a type for every column worked out from the data, a primary key, and INSERT statements in batches — for MySQL 8, MariaDB, PostgreSQL, SQLite, SQL Server and Oracle, each with its own identifier quoting, string escaping, date literals and limits.

Rows that may already exist can be inserted or updated (ON DUPLICATE KEY UPDATE, ON CONFLICT … DO UPDATE, MERGE) or skipped, everything can be wrapped in a transaction, and for big files the converter writes a bulk-load script instead — PostgreSQL COPY/\copy, MySQL LOAD DATA, SQLite .import, SQL Server BULK INSERT or an Oracle SQL*Loader control file — with a cleaned CSV that the loader reads. Files of hundreds of megabytes are read in pieces in the background; nothing is uploaded.

How to use it

  1. Paste your data into Your data, or choose Open file (CSV, TSV, TXT, JSON, JSON Lines, .xlsx, .xls, .ods). The delimiter, header row and decimal mark are detected; correct them if needed.
  2. Pick the database and the table name, and whether to create the table (optionally dropping an old one first).
  3. Check Columns: every column shows the type found in the data and examples. Rename columns, change a type, untick columns you do not need, and choose the primary key (or add an auto-increment id).
  4. Choose how rows are written — plain INSERT, insert or update (upsert) or skip rows that already exist — and the rows per statement.
  5. Copy the SQL, or Download .sql. For a bulk load, download the script and the cleaned CSV and run them as the notes describe.

Examples

CSV to PostgreSQL
Input
order_id,customer,order_date,amount,paid
1001,Asha Rao,03/10/2026,"1,250.50",yes
Result
CREATE TABLE "orders" (
  "order_id" integer NOT NULL,
  "customer" varchar(10) NOT NULL,
  "order_date" date NOT NULL,
  "amount" numeric(6,2) NOT NULL,
  "paid" boolean NOT NULL,
  PRIMARY KEY ("order_id")
);

INSERT INTO "orders" ("order_id", "customer", "order_date", "amount", "paid") VALUES
  (1001, 'Asha Rao', '2026-10-03', 1250.50, TRUE);

The date is read day-first (03/10/2026 = 3 October) — switch Dates to month-first for US data. 1,250.50 becomes the number 1250.50.

Insert or update on MySQL 8
Input
code,qty
A-1,5
Result
INSERT INTO `stock` (`code`, `qty`) VALUES
  ('A-1', 5) AS new
ON DUPLICATE KEY UPDATE `qty` = new.`qty`;

MySQL 8.0.19 and later use a row alias; for MariaDB the converter writes VALUES(qty) instead.

Text that needs escaping
Input
O'Brien \ Sons
Result
MySQL: 'O''Brien \\ Sons'   PostgreSQL: 'O''Brien \ Sons'   SQL Server: N'O''Brien \ Sons'

Common uses

  • Loading a spreadsheet or an export from another system into a database table.
  • Seed data and fixtures for development and tests.
  • Moving data between databases when only CSV is available.
  • Writing an idempotent import that can be run again without duplicating rows (upsert).

How column types are chosen

  • Integers become INT, BIGINT above 2,147,483,647, and DECIMAL above BIGINT’s range. Values with leading zeros (007), a + and a phone-length number, and columns named like phone, PIN code, account or card numbers stay text so nothing is lost.
  • Decimals become DECIMAL(p,s) sized to the longest number, so every digit is kept; exponents (1.5e-3) become floating point. Grouping commas (1,250.50, Indian 1,23,456.50) are removed; with Decimal mark: comma, 1.234,56 is read as 1234.56.
  • true/false, yes/no, t/f, y/n become boolean (TRUE/FALSE, or 1/0 where the database has no boolean). 1/0 columns stay integers.
  • Dates in ISO (2026-10-03), 03/10/2026, 3 Oct 2026 or Oct 3, 2026 form become DATE; with a time, a timestamp (fractions of a second kept); with Z or +05:30, a timestamp with time zone. When every date could be read either way, Dates decides.
  • UUIDs become uuid / UNIQUEIDENTIFIER / CHAR(36). Everything else is text, sized a little above the longest value (or unbounded TEXT if you prefer).
  • A column is NOT NULL when it has no empty cells. Empty cells, and the words under Also NULL, become NULL.

What differs between the databases

  • Names: backticks in MySQL and MariaDB, "double quotes" in PostgreSQL, SQLite and Oracle, [brackets] in SQL Server. Quoted names keep their case — choose snake_case or UPPER_CASE names if you want to type them without quotes later.
  • Strings: a quote is doubled everywhere; MySQL and MariaDB also need \\ for a backslash; SQL Server text is written N'…' so Unicode survives; Oracle literals over 4,000 bytes are joined from TO_CLOB pieces.
  • Batches: SQL Server accepts at most 1,000 rows in one VALUES list. Oracle rows are inserted with INSERT … SELECT … FROM dual UNION ALL, which works on every version and with identity columns.
  • Upsert: MySQL 8 ON DUPLICATE KEY UPDATE with a row alias, MariaDB with VALUES(), PostgreSQL and SQLite ON CONFLICT (key) DO UPDATE, SQL Server and Oracle MERGE. The key columns are never updated.
  • Transactions: START TRANSACTION / BEGIN … COMMIT; SQL Server adds SET XACT_ABORT ON so an error rolls everything back; Oracle scripts end with COMMIT and start with SET DEFINE OFF so an & in your data is not taken for a SQL*Plus variable.

Bulk loading big files

INSERT statements are fine for thousands of rows; for millions, the database’s own loader is much faster. Bulk-load script writes the loader command plus a cleaned CSV (only the included columns, numbers without grouping, ISO dates, booleans the loader understands, NULLs marked the way it expects): PostgreSQL \copy … FROM 'file.csv' for psql (or COPY … FROM STDIN with the rows inside the script), MySQL/MariaDB LOAD DATA LOCAL INFILE (needs local_infile), SQLite .import --csv --skip 1, SQL Server BULK INSERT … WITH (FORMAT = 'CSV') (2017 and later) and an Oracle SQL*Loader control file.

Limitations

  • Types are inferred from the data; review them before creating a production table — for example a column of 1s and 0s stays an integer.
  • One table at a time; foreign keys and indexes other than the primary key are not created.
  • PostgreSQL output assumes standard_conforming_strings = on (the default since 9.1), so backslashes in text are written as they are.
  • Dates with a time zone are kept as text on MySQL, MariaDB and SQLite, which have no such type.
  • Spreadsheet files are read up to 50 MB; CSV and TSV files of any size are read in pieces (the preview shows the first rows).

Privacy

Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.

Frequently asked questions

How do I convert a CSV file to SQL INSERT statements?

Open the CSV (or paste it), choose your database and table name, check the column types, then Download .sql. The file starts with CREATE TABLE (unless you turn it off) followed by INSERTs in batches.

Which database versions does the SQL work with?

MySQL 8.0.19+ (for the upsert row alias; plain INSERTs work on any version), MariaDB 10+, PostgreSQL 9.5+ (ON CONFLICT; identity columns need 10+), SQLite 3.24+ (upsert), SQL Server 2016+ (DROP TABLE IF EXISTS; BULK INSERT CSV needs 2017+) and Oracle 12c+ (identity columns).

Why is my number column text?

Every value must be a number for a numeric type: one N/A, ₹500, 12% or a value with a leading zero keeps the whole column as text so nothing is lost. Add N/A to Also NULL, or change the column’s type — values that still do not fit are written as text and listed in the notes.

How do I avoid duplicate rows when I run the import again?

Choose a primary key column and set Rows to Insert or update (existing rows are updated) or Skip rows that already exist (existing rows are left alone). If the file itself repeats a key, the notes say what your database does with it: an upsert on PostgreSQL, and a MERGE on SQL Server or Oracle, refuse the same key twice in one statement — remove the repeats, or set Rows per INSERT to 1.

Is my data uploaded?

No. Reading, type detection and SQL generation all happen in your browser — large files in a background worker on your device.

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.