Skip to content
alpaca.tools

CSV to SQL

Loading CSV to SQL...
5.01 rating50 uses
Your rating for CSV to SQLYour rating
Data Tools

About CSV to SQL

Paste a CSV or drop a file and get SQL as you type: a CREATE TABLE with column types read from your data, then INSERT statements in batches or upserts on a key column. Pick PostgreSQL, MySQL/MariaDB, SQLite or SQL Server, and quoting and escaping follow that dialect. You can rename, retype or leave out any column, and the SQL to CSV mode turns INSERT statements back into a CSV file.

CSV to SQL converter with column types

The converter reads the header row for column names and checks every value to pick a type, then writes a CREATE TABLE in the dialect you choose. Headers are turned into snake_case (Product Name becomes product_name), empty or repeated headers get names like column_3 or name_2, and names longer than the database allows are shortened. Choose As in header under More options to keep the original names.

Columns with no empty cells get NOT NULL, and a column named id with unique values becomes the primary key. The Columns table shows the first rows under each column so you can confirm the delimiter and types before copying.

  • Whole numbers: INTEGER or BIGINT (INT in MySQL and SQL Server)
  • Decimals: NUMERIC(p,s) in PostgreSQL, DECIMAL(p,s) in MySQL and SQL Server
  • true/false, yes/no: BOOLEAN, TINYINT(1) in MySQL, BIT in SQL Server
  • YYYY-MM-DD: DATE
  • ISO date-times: TIMESTAMP, DATETIME in MySQL, DATETIME2 in SQL Server, with TIMESTAMPTZ or DATETIMEOFFSET when values include a time zone
  • Anything else: TEXT in PostgreSQL and SQLite, VARCHAR(n) in MySQL, NVARCHAR(n) in SQL Server

CSV to SQL INSERT statements

Rows are written as multi-row INSERT statements with 100 rows each. Under More options you can write one INSERT per row or up to 1,000 rows per statement, add DROP TABLE IF EXISTS before the CREATE TABLE, and wrap the inserts in a transaction. Empty cells, and cells that contain NULL or \N, become NULL; turn that off to insert empty strings instead.

Switch Statements to Upsert to update rows that already exist. The key column decides what counts as the same row, and the statement follows the dialect: ON CONFLICT DO UPDATE for PostgreSQL and SQLite, ON DUPLICATE KEY UPDATE for MySQL, and MERGE for SQL Server. If the key column repeats a value, a note points to the line, since the database would reject it.

CSV to MySQL and MariaDB

With MySQL / MariaDB selected, names are quoted with backticks and text values escape backslashes and line breaks the way MySQL expects. Text columns up to 255 characters become VARCHAR sized to fit the longest value, longer ones TEXT, and booleans become TINYINT(1) with TRUE and FALSE values. Date-times with a time zone, like 2024-05-01T09:00:00Z or +02:00, are converted to UTC and written without the offset, because DATETIME stores no zone and MariaDB rejects offsets. Values with fractional seconds get DATETIME(n) so the fractions are kept.

For very large files, MySQL's LOAD DATA LOCAL INFILE is faster than running INSERT statements. You can still use this tool to get the CREATE TABLE with the right types, then load the CSV into that table.

SQL to CSV: turn INSERT statements into a CSV file

Use the SQL to CSV switch at the top to go the other way. Paste a dump or a few INSERT statements and the rows come out as CSV with a header row. Quoted strings with doubled quotes, N'...' and E'...' strings, negative numbers and NULL are decoded, and comments, SET statements and ON CONFLICT clauses are skipped. Expressions such as NOW() or CAST(...) are kept as written.

Values that contain commas, quotes or line breaks are quoted in the CSV, and you can pick a comma, semicolon, tab or pipe as the delimiter. The download is named after the table, for example customers.csv.

FAQ

Drop the .csv file on the CSV box or click Open file, pick your database, and check the table name and the Columns table. The SQL updates as you change anything. Click Copy SQL, or Download to save a .sql file. The file name becomes the table name, so customers.csv gives CREATE TABLE customers.

Every non-empty value in a column is checked. Whole numbers become INTEGER or BIGINT, decimals DECIMAL with enough digits for the largest value, true/false and yes/no BOOLEAN, YYYY-MM-DD dates DATE, and ISO date-times TIMESTAMP. If one value does not fit, the column becomes text. Numbers with leading zeros, like ZIP codes, also stay text so the zeros are kept. Each type is written in the dialect's own name, for example TINYINT(1) for a boolean in MySQL and BIT in SQL Server. You can change any type in the Columns table; values that do not fit the new type are highlighted and written as quoted text.

Yes. Single quotes inside values are doubled in every dialect. For MySQL, backslashes, line breaks and NUL characters are also escaped, which matches MySQL's default sql_mode. SQL Server text is written as N'...' so accented and non-Latin characters are kept. Table and column names are quoted with double quotes, backticks or brackets depending on the dialect, so names like order or First Name work, and a value such as '); DROP TABLE users; -- stays plain text.

Files up to 50 MB. A 50,000-row, 6.6 MB CSV takes about half a second to convert on a desktop computer, and longer on a phone. The output box shows the first 2,000 lines, and Copy and Download include every row. Files over 1 MB are shown as a file card instead of in the text box, because editing that much text in a page is slow.

Choose SQL Server, copy the script and run it in SSMS or sqlcmd. SQL Server accepts at most 1,000 rows in one VALUES list, so larger batches are split into several INSERT statements automatically. For files with millions of rows, run only the CREATE TABLE from this tool and load the data with BULK INSERT dbo.customers FROM 'C:\data\customers.csv' WITH (FORMAT = 'CSV', FIRSTROW = 2), which reads the file on the server (SQL Server 2017 or later).

Yes. Switch to SQL to CSV and paste INSERT statements or open a .sql file. Single and multi-row INSERTs work, with or without a column list; when there is no column list, the column names come from a CREATE TABLE in the same script. pg_dump COPY blocks are read too. NULL becomes an empty cell. If the script has rows for several tables, pick the table to export. Choose MySQL as the dialect when the dump uses backslash escapes like \' or \n.