Home/Articles/Import CSV into SQL Server

The Ultimate Guide to Importing CSV Files into SQL Server: 5 Proven Methods

From the SSMS wizard to the BCP command-line utility — the right tool for every scale, with troubleshooting for the errors that always come up.

10 min read·Data Onboarding Fundamentals

Whether you are migrating legacy data, ingesting third-party reports, or automating weekly updates, moving data from a flat file into a relational database is a foundational skill. SQL Server offers five distinct tools for this — each optimized for a different scale, workflow, and skill level.

Pick your method

Use caseRecommended toolSkill level
Quick, one-time importImport/Export Wizard (SSMS)Beginner
Automated script / stored procedureBULK INSERT (T-SQL)Intermediate
High performance / millions of rowsBCP Utility (CLI)Intermediate
Query a file without importing itOPENROWSETAdvanced
Complex data cleaning / ETLSSISAdvanced

If you work across multiple database platforms, this guide focuses on the SQL Server (MSSQL) ecosystem. For the PostgreSQL equivalent — which uses COPY and \copy instead of BULK INSERT and BCP — see the complete PostgreSQL import guide.

Method 1: The SSMS Import/Export Wizard — GUI, No Code Required

For many users, the Import and Export Wizard is the first point of contact. It is built directly into SQL Server Management Studio (SSMS) and provides a visual, step-by-step process with no SQL required.

Step-by-step

  1. Right-click your database in SSMS → Tasks → Import Data.
  2. Data Source: Select "Flat File Source" and browse to your CSV.
  3. Destination: Select "SQL Server Native Client" or OLE DB Provider for SQL Server.
  4. Edit Mappings: Verify data types (varchar vs int) match your expectations.
  5. Click Finish to execute the transfer.

The wizard is useful for one-off imports and can auto-create the destination table by inferring types from the file. The same type-inference caveat that applies to pgAdmin applies here: automated tools default to the widest possible types, which may need tightening for production use.

Method 2: BULK INSERT — The Scripting Standard

When you need your import process inside a stored procedure or SQL script, BULK INSERT is the right tool. It uses minimal logging and is significantly faster than row-by-row INSERT statements. The concept is the same as PostgreSQL's COPY command — if you're familiar with one, the other maps directly.

-- Create the target table first
CREATE TABLE Employees (
    EmpID     INT,
    FirstName VARCHAR(50),
    LastName  VARCHAR(50),
    HireDate  DATE
);

-- Execute the bulk load
BULK INSERT Employees
FROM 'C:\Data\EmployeeList.csv'
WITH (
    FORMAT          = 'CSV',
    FIRSTROW        = 2,        -- Skip the header row
    FIELDTERMINATOR = ',',
    ROWTERMINATOR   = '\n',   -- Use '\r\n' for Windows line endings
    TABLOCK                     -- Minimizes logging; locks table for speed
);

SQL Server version caveat

The FORMAT = 'CSV' argument requires SQL Server 2017 or later. On older versions, remove that line and rely solely on FIELDTERMINATOR and ROWTERMINATOR.

Method 3: The BCP Utility — Maximum Throughput from the CLI

For massive datasets — millions of rows — the BCP (Bulk Copy Program) utility is the fastest tool available. It runs as a standalone command-line process outside the SQL Server process, giving it extremely low overhead. Think of it as the SQL Server equivalent of the PostgreSQL psql \copy command, but with even more configuration flags.

bcp MyDatabase.dbo.Employees in "C:\data\input.csv" ^
  -c ^          # Character mode — correct for CSV
  -t,  ^        # Comma as field terminator
  -S MyServer ^ # Server name
  -T            # Trusted connection (Windows Auth)
  • in — importing. Use out for exporting.
  • -c — character mode; the right choice for text CSV files.
  • -T — uses Windows Authentication (trusted connection). Replace with -U and -P for SQL auth.

Method 4: OPENROWSET — Query Without Importing

Sometimes you don't want to load the data into a permanent table at all — you just need to join it against existing data for a one-time report. OPENROWSET lets you query a CSV file as if it were a SQL table.

SELECT a.*
FROM OPENROWSET(
    BULK 'C:\Data\RecentSales.csv',
    SINGLE_CLOB  -- Reads the file as a single large object
) AS a;

Server configuration required

OPENROWSET requires "Ad Hoc Distributed Queries" to be enabled on the server (sp_configure). Complex file structures also need a format file (.fmt). This is not a lightweight option — use BULK INSERT if you're just loading data.

Method 5: SSIS — When the Data Needs Transformation

If your import isn't a straight line — data needs cleaning, currencies need converting, or you're merging multiple files — you need an ETL tool. SQL Server Integration Services (SSIS) is Microsoft's enterprise platform for data integration.

When SSIS is the right choice

  • Data requires transformation before it can land in the schema.
  • You need to import hundreds of files in a loop.
  • You need advanced error handling — "if a row fails, quarantine it but continue importing the rest."

For the Postgres equivalent of this quarantine pattern without a full ETL platform, see the staging table strategy.

Troubleshooting Common Errors

Even with the right tool, CSV imports can fail in predictable ways. Here are the four errors that come up most often — and the exact fix for each.

"Access Denied" on the file

Why it happens: The SQL Server service account (not your Windows login) must have read permissions on the folder containing the CSV. You can see the file; SQL Server cannot.

Fix: Grant read access to the SQL Server service account on the folder — or copy the file to a shared location like C:\\Temp\\ that the service account can reach.

Data truncation errors

Why it happens: A string in the CSV is longer than the column definition (e.g., 100-char value into VARCHAR(50)).

Fix: Use a staging table with VARCHAR(MAX) columns to get the raw data in first, then clean and cast before inserting into the production table. This is the same staging approach described in the PostgreSQL context.

Date format mismatches

Why it happens: Your CSV uses DD/MM/YYYY but SQL Server expects MM/DD/YYYY — dates either import wrong or as NULL.

Fix: Import date columns as VARCHAR first, then use TRY_CONVERT(DATE, DateColumn, 103) to transform them safely without aborting the import.

IDENTITY column conflicts

Why it happens: SQL Server auto-generates IDs for IDENTITY columns, ignoring whatever IDs are in the CSV file.

Fix: Add the KEEPIDENTITY hint to your BULK INSERT statement to force SQL Server to use the IDs from the file instead of generating new ones.

Many of these errors — type mismatches, encoding issues, empty string nulls — appear in identical form on PostgreSQL. The PostgreSQL import troubleshooting guide covers the parallel fixes if you work across both platforms.

Skip the tool selection entirely

Elvity's automated onboarding engine validates, maps, and loads CSV data into any database — SQL Server, PostgreSQL, or both — without stored procedures, BCP scripts, or SSIS packages.