Home/Articles/CSV to Azure SQL Database

Migrating CSV Data to Azure SQL Database: Tools and Techniques

Azure SQL Database cannot read files from your local drive — every import method needs a network bridge. Here is how each tool creates that bridge, when each one is the right choice, and what the common failure points look like.

10 min read·Azure SQL · Cloud Data Migration

The fundamental difference between migrating data to an on-premise SQL Server and migrating it to Azure SQL Database is file access. An on-premise SQL Server is a Windows machine on your network — you can give its service account access to a local folder, and BULK INSERT can read directly from disk. Azure SQL is a managed service running in Microsoft's data centers. Its compute engine has no access to your local file system, and even if you try to run BULK INSERT with a local path, the statement will fail immediately with a path-not-found error.

Every migration technique covered in this guide solves this problem differently. Understanding which bridge each tool uses — and what that means for file size limits, authentication, and repeatability — is more useful than a list of steps.

Before You Start: Two Blockers That Affect Every Method

These two issues cause the majority of failed Azure SQL import attempts, regardless of which tool you use. Resolving them before starting any migration saves significant troubleshooting time.

Firewall rules on the Azure SQL server

Azure SQL Database blocks all inbound connections by default. To connect from any external tool — SSMS, Azure Data Studio, ADF, a script — you must add your IP address to the server-level firewall in the Azure Portal: SQL servers → [your server] → Networking → Add your client IP. If you are in an office with a dynamic IP or behind a corporate proxy, the IP displayed in the Portal may differ from the one Azure sees. The easiest test: try to connect from SSMS. If it times out or returns "Login failed" before even prompting for credentials, the firewall is blocking the connection.

Authentication mode on the Azure SQL server

Azure SQL supports two authentication modes: SQL Authentication (username and password stored in the database) and Azure Active Directory (Azure AD) authentication. By default, newer Azure SQL servers are created with Azure AD-only authentication and no SQL login. If your tool or script tries to connect with a SQL username and password and receives "Cannot open server requested by the login," the server may have SQL Authentication disabled. Check under SQL servers → [your server] → Azure Active Directory → and note whether "Support only Microsoft Entra authentication" is toggled on. Enable SQL Authentication if you need it, or use an Azure AD account.

Method 1: Azure Data Studio with the SQL Server Import Extension

Azure Data Studio is a cross-platform database client (Windows, Mac, Linux) that Microsoft positions as the modern replacement for SSMS for day-to-day query and management work. The "SQL Server Import" extension adds a CSV-to-table wizard that can connect to Azure SQL and upload data directly from a local file. It is the fastest path for a one-time migration of a file that fits comfortably in memory.

The extension streams the CSV from your machine to Azure SQL over the TDS (Tabular Data Stream) protocol — the same connection used for normal queries. This means the transfer speed is limited by your upload bandwidth and the connection latency to the Azure region hosting your database. For files under a few hundred thousand rows, this is not a noticeable constraint. For files in the millions, this method becomes impractical.

SQL Server Import extension — key configuration points

StepWhat to doCommon mistake
Install the extensionExtensions panel → search "SQL Server Import" → InstallThe extension is not bundled — it must be installed separately even on a fresh ADS install
Connect to Azure SQLNew Connection → enter server FQDN (e.g., myserver.database.windows.net), database, and credentialsUsing the server name without the .database.windows.net suffix causes a connection failure
Select the destination databaseRight-click the database in the Connections pane → Import WizardRight-clicking the server (not the database) opens a different context menu without the import option
Column type previewThe wizard samples the CSV and suggests types — review every column before acceptingSparse columns or columns with leading nulls get incorrect type suggestions; override string columns to NVARCHAR(MAX) when uncertain
New table vs existing tableThe wizard creates a new table by default — if the table exists, you must select it explicitlyAccepting the default creates a duplicate table with a generated name

Method 2: Azure Blob Storage + BULK INSERT / OPENROWSET

For large files or for any situation where you want a reliable, repeatable, high-performance import, the correct pattern is to stage the CSV in Azure Blob Storage first, then have Azure SQL pull it from there. Because both Blob Storage and Azure SQL live in Azure's network, the actual data transfer happens cloud-to-cloud — your local internet connection is only involved in the initial upload to Blob Storage, which you can do once and retry if it drops.

Once the file is in Blob Storage, Azure SQL can read it using BULK INSERT with a Shared Access Signature (SAS) URL, or using OPENROWSET with the same credential. The BULK INSERT option table applies here — TABLOCK, BATCHSIZE, FIRSTROW, and FORMAT = 'CSV' all work the same way in Azure SQL as in on-premise SQL Server. The only difference is the file path: instead of a Windows folder path, you provide the Blob Storage URL.

1

Upload the CSV to Azure Blob Storage

Use Azure Storage Explorer (a free desktop tool) or the Azure Portal's Storage Browser to upload the file to a container. Create a container dedicated to imports (e.g., "csv-imports") so it's easy to manage access separately from other storage. Storage Explorer can upload files of any size and handles interruptions — it resumes where it left off.

2

Create a Shared Access Signature (SAS) token

A SAS token is a time-limited, permission-scoped credential that Azure SQL uses to authenticate against Blob Storage without requiring your full account key. In Azure Portal → Storage account → Containers → [container] → Shared access tokens → set Read permission and an expiry that covers the import window. Copy the SAS URL — it includes both the blob path and the credential.

3

Create a DATABASE SCOPED CREDENTIAL

In Azure SQL, run a T-SQL statement to store the SAS token as a database-scoped credential. This keeps the credential inside the database rather than embedded in the query text. Name the credential after the blob service URL (e.g., https://[account].blob.core.windows.net). The credential is then referenced by BULK INSERT or OPENROWSET when accessing that storage account.

4

Run BULK INSERT referencing the Blob Storage URL

The BULK INSERT statement targets the Blob Storage URL instead of a local path. All the standard performance options apply: FORMAT, FIRSTROW, TABLOCK, BATCHSIZE, ERRORFILE. The ERRORFILE path must also be a Blob Storage URL when running in Azure SQL — you cannot redirect errors to a local drive.

Keep the Blob Storage account in the same Azure region as the database

Blob Storage in the same Azure region as your Azure SQL server transfers data over Microsoft's internal network backbone — no egress charges and near-LAN speeds. Cross-region transfers incur both egress charges and latency. When creating the Storage account, select the same region as your Azure SQL server (visible in the Azure Portal under SQL databases → [your db] → Overview → Location).

Method 3: Azure Data Factory

Azure Data Factory is Microsoft's cloud ETL service — the managed cloud equivalent of SSIS for teams that don't want to manage SSIS infrastructure. ADF pipelines are configured through a browser-based designer and run on Microsoft-managed integration runtimes, with no local tooling to install beyond the Azure Portal.

For CSV-to-Azure-SQL specifically, ADF's Copy Data activity reads from a source (Blob Storage, SFTP, HTTP, local file via a Self-Hosted Integration Runtime) and writes to a destination (Azure SQL). The Copy Data wizard handles connection configuration, schema mapping, and type conversion through a guided interface. The result is a reusable pipeline that can be triggered on a schedule, by an event (e.g., a new file landing in Blob Storage), or via REST API.

ADF Copy Data activity — key configuration decisions

Decision pointOptionWhen to use it
Integration runtimeAzure IR (default)Source data is already in Azure (Blob Storage, SFTP, HTTP endpoint)
Integration runtimeSelf-Hosted IRSource data is on a local machine or behind a corporate firewall — a small agent is installed on-premise
Source linked serviceAzure Blob StorageFile is uploaded to Blob Storage first — fastest and most reliable path
Source linked serviceHTTP datasetCSV is hosted at a public URL (e.g., a data feed from a vendor) — ADF fetches it on each trigger
Copy methodBulk insert (default)Maximum throughput — ADF uses BULK INSERT internally for Azure SQL destinations
Copy methodUpsertWhen re-running the pipeline should update existing rows rather than inserting duplicates — requires a key column
Trigger typeScheduleFixed frequency (daily, hourly) — configured in trigger settings
Trigger typeStorage eventRuns automatically when a new blob is created in the source container — no fixed schedule needed
Fault toleranceSkip incompatible rowsAllows the pipeline to continue past type-mismatch errors and log rejected rows to a separate blob

ADF vs SSIS: the managed vs self-managed tradeoff

SSIS requires you to manage the server or Azure-SSIS Integration Runtime that runs packages. ADF's Azure Integration Runtime is fully managed — Microsoft scales it, patches it, and makes it available without any infrastructure management on your side. ADF is the better choice for new cloud-native pipelines. SSIS remains relevant when migrating existing SSIS packages to the cloud (Azure-SSIS IR can run .dtsx packages without modification) or when the pipeline requires components that don't have ADF equivalents.

Method 4: SSMS Import and Export Wizard

The SSMS Import and Export Wizard works against Azure SQL in the same way it works against on-premise SQL Server — you connect via a standard connection string, select the source (a local CSV), and run the wizard. The data travels row-by-row over the same TDS connection used for normal queries, from your local machine across the internet to Azure SQL.

This method is familiar and requires no additional tools beyond SSMS, but the row-by-row transfer mechanism means it is fundamentally slower than Blob Storage + BULK INSERT for large files. At 10,000 rows per second (a generous estimate over a typical business internet connection), a 5-million-row file takes over 8 minutes. The same file loaded from Blob Storage via BULK INSERT typically lands in under 2 minutes. For one-time migrations of small files where you already have SSMS open, the wizard is acceptable. For any recurring import or for files over a few hundred thousand rows, use a different method.

Choosing the Right Tool

SituationBest toolWhy
One-time import, file under 500k rowsAzure Data Studio + SQL Server Import extensionFastest setup, no extra Azure services needed, type detection built in
One-time import, file over 100MBBlob Storage + BULK INSERTAvoids timeout risk, cloud-to-cloud transfer, no bandwidth dependency
Recurring scheduled import from a fixed locationAzure Data Factory (Schedule trigger)Managed infrastructure, built-in retry logic, monitoring in the Azure Portal
Event-driven import (new file → trigger load)Azure Data Factory (Storage event trigger)Near-real-time processing without polling on a fixed schedule
Import with on-the-fly transformation or enrichmentAzure Data Factory (Mapping Data Flows)Visual column mapping, expression-based transformation, no external compute needed
Familiar with SSMS, small file, one-time taskSSMS Import WizardNo additional setup, existing tooling, acceptable for small volumes
Migrating from on-premise SSIS packagesAzure-SSIS Integration Runtime in ADFRuns existing .dtsx packages unchanged in the cloud without redesign

Azure Blob Storage: The Common Thread

Three of the four methods above either require or work best with Azure Blob Storage as an intermediate staging layer. Blob Storage in Azure is the equivalent of Amazon S3 — it is the standard object store for unstructured data, and it is deeply integrated with every Azure data service. ADF's most reliable source connectors target Blob Storage. BULK INSERT from Azure SQL targets Blob Storage URLs. Azure Synapse, Azure Databricks, and Azure Machine Learning all read from Blob Storage natively.

Getting comfortable with Blob Storage — understanding containers, access tiers (Hot vs Cool vs Archive), SAS tokens, and lifecycle policies — is the single highest-leverage skill for anyone working with data in Azure long-term. If you expect to migrate data to Azure SQL more than once, set up a dedicated Storage account for it now. The time investment is small and it removes the file-access constraint from every future migration.

Blob Storage concepts every Azure SQL user should know

ConceptWhat it isWhy it matters for CSV import
ContainerA logical grouping of blobs inside a Storage account, similar to a top-level folderCreate a separate container for import staging so you can set SAS permissions at the container level without exposing other blobs
SAS tokenA time-limited, permission-scoped URL that grants access to a specific blob or containerUsed as the credential in DATABASE SCOPED CREDENTIAL so Azure SQL can authenticate against Blob Storage without your account key
Access tierHot (frequent access), Cool (infrequent), Archive (rare) — affects cost per GB and retrieval latencyUse Hot tier for the import container — Cool and Archive tiers have retrieval delays that cause BULK INSERT timeouts
Soft deleteA setting that retains deleted blobs for a configurable number of days before permanent removalEnable it on the import container to recover accidentally deleted CSV files before the next import run
Lifecycle policyRules that automatically move or delete blobs after a specified number of daysSet a policy to auto-delete blobs from the import container after 30 days to prevent unbounded storage growth

Automated CSV ingestion for Azure SQL, without the configuration

Elvity handles Blob Storage staging, SAS credentials, BULK INSERT configuration, and scheduling — without manual pipeline setup in ADF or SSMS.