How to import Excel into a database

The simplest way to import Excel into a database is to turn the sheet into SQL: a CREATE TABLE statement with fitting column types plus INSERT statements for the rows, which you run in SQL Server Management Studio, MySQL Workbench, pgAdmin or any client. The converter on this page writes that SQL in your browser for SQL Server, MySQL, PostgreSQL and SQLite; for millions of rows, export CSV and use the database's bulk loader instead.

6 min read

The short answer

A database cannot read an .xlsx file by itself. Something has to read the sheet, decide what type each column is, create a table and insert the rows. You can let your database's import wizard do it, load a CSV with a bulk command, or generate plain SQL that any database client can run.

Generated SQL is the most portable option and the easiest to check, because you see exactly what will be created before anything touches the database. In the converter below, open the .xlsx or .csv file (or paste cells copied from Excel), choose the Database, type the Table name, and copy or download the script. Column types are detected from the data, and barcodes or codes with leading zeros stay text.

Try it here: Excel to SQL

Open the full tool page

Prepare the sheet first

Most failed imports are caused by the spreadsheet, not the database. Spreadsheets are made for people; tables need one clean rectangle of data. Spend two minutes on this before importing anything:

  • Exactly one header row with unique column names. Remove titles above the table, merged header cells and second header rows.
  • One row per record. Delete total and subtotal rows, blank separator rows and notes below the data.
  • One kind of value per column. A Price column should not contain the text on request in some rows; use an empty cell instead, which becomes NULL.
  • No merged cells inside the data. Unmerge them and fill the value into every row it applies to.
  • Formulas are fine: the last calculated value saved in the file is used. Make sure the workbook was recalculated and saved after the last change.
  • Put each table on its own sheet. When a workbook has several sheets, the converter shows a Sheet selector.

Methods compared

MethodGood forWatch out for
Generated SQL (this page)Up to tens of thousands of rows, any database, reviewable scriptVery large files make very large scripts
SQL Server Import and Export WizardRegular imports into SQL ServerReading .xlsx needs the Microsoft Access Database Engine; 32 bit and 64 bit versions must match
SSMS Import Flat FileCSV into SQL ServerCheck the guessed types before finishing
BULK INSERT (SQL Server), LOAD DATA (MySQL), COPY (PostgreSQL)Millions of rows from CSVFile access rights on the server, delimiter and encoding options
MySQL Workbench Table Data Import WizardCSV or JSON into MySQLSlow on large files
pgAdmin Import/ExportCSV into an existing PostgreSQL tableThe table must exist first
The .import command of the sqlite3 shell (csv mode)CSV into SQLiteColumns are created as TEXT unless the table exists

Step by step with generated SQL

  • Open the file or paste the cells. The first row becomes the column names; turn off First row is header if your data has none.
  • Choose the Database: SQL Server, MySQL, PostgreSQL or SQLite. Quoting, types and escaping change with it.
  • Type the Table name. With Simplify names on, Product Name becomes product_name, which saves you from quoting names in every later query.
  • Pick Rows per INSERT. 100 is a safe default; larger batches import faster. SQL Server accepts at most 1000 rows in one VALUES list, so the tool never goes above that for SQL Server.
  • Decide on the extras: CREATE TABLE writes the table definition, Drop table first removes an existing table with the same name (only use it on tables you mean to replace), and Use a transaction makes the import all or nothing.
  • Copy the SQL or download the .sql file, then run it in your database client.

Column types the converter chooses

Each column gets the narrowest type that fits every value in it. Text columns get a length rounded up from the longest value (for example VARCHAR(50) for a 37 character maximum), so you can still widen them later if needed.

Data in the columnSQL ServerMySQLPostgreSQLSQLite
Whole numbersINT or BIGINTINT or BIGINTINTEGER or BIGINTINTEGER
DecimalsDECIMAL(p, s)DECIMAL(p, s)NUMERIC(p, s)REAL
true or falseBITTINYINT(1)BOOLEANINTEGER
DatesDATEDATEDATETEXT
Date and timeDATETIME2DATETIMETIMESTAMPTEXT
Text, codes with leading zerosNVARCHAR(n)VARCHAR(n)VARCHAR(n)TEXT

Common problems and how to avoid them

  • Dates arrive as numbers like 45000. Excel stores dates as day counts (45000 is 15 March 2023). When you read an .xlsx with the converter, date cells are turned back into real dates; other tools may need the column formatted as a date first.
  • Leading zeros disappear. Barcodes, postal codes and product codes like 00123 must be text. The converter keeps a column as text when its values start with zero, and numbers longer than 15 digits also stay text.
  • Accented letters become question marks in SQL Server. Unicode text needs NVARCHAR columns and the N prefix on string literals; the generated SQL Server script uses both. In MySQL, use a utf8mb4 table.
  • Decimal comma numbers. In semicolon separated CSV files, values like 1.499,90 are read as 1499.90. In comma separated files the comma is a column separator, so such values must be quoted.
  • Empty cells. They become NULL and the column is created as nullable. If you want empty text instead, change it after the import.
  • Quotes inside text. An apostrophe in O'Brien would break a hand written INSERT; generated values are escaped, and MySQL backslashes are escaped too.

When to use a bulk loader instead

INSERT scripts are perfect for a few thousand to tens of thousands of rows: you can read them, keep them in version control and run them anywhere. For hundreds of thousands or millions of rows, the script gets very large and running it is slower than a bulk load.

In that case, save the sheet as CSV UTF-8 and use the bulk command of your database: BULK INSERT in SQL Server, LOAD DATA LOCAL INFILE in MySQL, COPY or psql's \copy in PostgreSQL. A useful middle path is to let the converter write only the CREATE TABLE statement from a sample of the data, so you get sensible column types, and then load the full CSV into that table with the bulk command.

Step by step

  1. Add the dataOpen an .xlsx or .csv file, or copy cells in Excel and paste them into the input box.
  2. Choose database and tablePick SQL Server, MySQL, PostgreSQL or SQLite under Database and type the Table name.
  3. Set the optionsChoose Rows per INSERT and tick CREATE TABLE, Drop table first, Use a transaction or Simplify names as needed.
  4. Check the column typesRead the CREATE TABLE part of the result and make sure codes are text and numbers are numeric.
  5. Run the SQLCopy the script or download the .sql file and run it in your database client.

Frequently asked questions

Can I import an Excel file directly into SQL Server?

Yes, with the SQL Server Import and Export Wizard, but reading .xlsx requires the Microsoft Access Database Engine on the machine. Generating INSERT statements avoids that dependency and works with any SQL Server client.

Is my spreadsheet uploaded to convert it?

No. The file is read and the SQL is generated in your browser. Nothing is sent to a server, which matters for customer lists and price files.

How many rows can I import with INSERT statements?

Tens of thousands of rows work well. For millions of rows, use a bulk loader such as BULK INSERT, LOAD DATA or COPY with a CSV file.

Are old .xls files supported?

No. Open the file in Excel or LibreOffice, save it as .xlsx, and open that copy. CSV files work as well.

Can I add rows to an existing table?

Yes. Turn off CREATE TABLE and Drop table first, type the existing table name, and make sure the column names match. Only the INSERT statements are written.

Does it work offline?

Yes. After the page has been opened once, it keeps working without an internet connection.