The most common first step away from a pure Access database is not abandoning Access entirely. It is keeping your Access forms, reports, and VBA code while moving the data to SQL Server. This is sometimes called “upsizing” and it is the least disruptive migration path available.
Here is how it works, what changes, and what to watch out for.
The Basic Architecture
In a pure Access database, everything lives in one file — tables, queries, forms, reports, macros, and VBA modules. In a split architecture, you separate these into two pieces:
- Front-end: An
.accdbfile containing your forms, reports, queries, macros, and VBA code. Each user gets their own copy of this file on their local machine. - Back-end: A SQL Server database containing all your tables and data. This runs on a server (local or cloud) and handles all data storage and retrieval.
The front-end connects to the back-end using ODBC (Open Database Connectivity) linked tables. From the user’s perspective, the forms look and work the same. Behind the scenes, every data operation goes through SQL Server instead of reading and writing to a shared file.
What Changes for Users
In a well-executed migration, users should notice very little change in how they interact with the database. Their forms look the same. Their reports run the same way. The buttons they click do the same things.
What they will notice:
- Better performance with multiple users. SQL Server handles concurrent access properly. No more waiting for locks, no more write conflicts, no more frozen forms when ten people are in the database at once.
- Faster queries on large tables. SQL Server processes queries on the server and sends back only the results, instead of pulling entire tables across the network.
- No more corruption emergencies. SQL Server uses transaction logging and crash recovery. The days of running Compact and Repair or restoring from backup are over.
How ODBC Linked Tables Work
The connection between your Access front-end and SQL Server back-end is built on ODBC linked tables. Here is how they work:
- You set up an ODBC data source (DSN) or use a DSN-less connection string that tells Access where to find the SQL Server instance, which database to use, and how to authenticate.
- In Access, you create linked tables that point to the SQL Server tables. These appear in your table list with a small globe icon instead of the usual table icon.
- When your forms or queries reference these tables, Access translates the request into an ODBC call to SQL Server. SQL Server processes the request and returns the results.
For simple operations — opening a form bound to a table, running a select query, inserting or updating records — this translation is seamless. Access sends the SQL command to SQL Server, gets the results back, and populates the form.
What You Need to Set Up
On the Server Side
- SQL Server instance. This can be SQL Server Express (free, limited to 10GB databases), SQL Server Standard, or an Azure SQL database. For most Access migrations, Express is sufficient to start.
- The database. You need to migrate your Access tables to SQL Server. Microsoft provides the SQL Server Migration Assistant (SSMA) tool for this, or you can do it manually.
- Authentication. Either Windows Authentication (uses Active Directory credentials) or SQL Server Authentication (username and password). Windows Authentication is simpler if everyone is on the same domain.
On Each Workstation
- ODBC driver. The SQL Server ODBC driver needs to be installed. Modern Windows versions include a basic driver, but you should install the latest Microsoft ODBC Driver for SQL Server.
- The front-end file. Each user gets a copy of the
.accdbfile containing the forms and linked tables. - Network access. The workstation needs to reach the SQL Server instance over the network (typically port 1433).
What Breaks (And How to Fix It)
Moving to SQL Server is not a transparent drop-in replacement. Several things work differently, and your existing queries and VBA code may need adjustments.
Data Type Differences
Access and SQL Server use different data types. Most map cleanly, but a few cause problems:
- Yes/No fields in Access become
bitin SQL Server. This usually works, but some VBA code that treats True as-1may behave differently since SQL Server uses1. - Memo fields become
nvarchar(max). Generally fine, but some Access-specific functions on memo fields may not work through ODBC. - AutoNumber becomes
int identity. This works seamlessly for most purposes. - Date/Time fields can cause issues if your Access database stores dates as text strings in some places. SQL Server is stricter about date formats.
Query Syntax
Access SQL and T-SQL (SQL Server’s dialect) are not identical. Common issues:
- Access uses
IIf()— SQL Server usesCASE WHEN ... THEN ... ELSE ... END - Access uses
&for string concatenation — SQL Server uses+ - Access uses
*as a wildcard inLIKE— SQL Server uses% - Access allows column aliases in
WHEREclauses — SQL Server does not
If your queries run entirely through the linked table interface (bound forms, simple SELECT queries), Access handles the translation automatically. But if you have pass-through queries or complex VBA code that builds SQL strings, you will need to rewrite those using T-SQL syntax.
VBA Code
Most VBA code that interacts with data through forms and bound controls continues to work without changes. The problems arise in code that:
- Opens recordsets directly using
CurrentDb.OpenRecordset— these still work but may need thedbSeeChangesoption for tables with identity columns. - Builds SQL strings and executes them with
DoCmd.RunSQL— the SQL syntax may need to change. - Uses Access-specific functions like
DLookup,DCount, orDSum— these still work but are slow because they execute as separate queries over ODBC.
Performance Gotchas
The biggest performance trap is Access pulling more data than necessary over ODBC. Common causes:
- Unbound forms that load entire tables. If a form loads all 50,000 records at startup, that data all travels over ODBC. Add filtering so users only load what they need.
- Heterogeneous joins. If you join a local Access table with a linked SQL Server table, Access pulls the entire SQL Server table locally to perform the join. Move both tables to SQL Server or restructure the query.
- DLookup in forms. Each
DLookupcall on a linked table is a separate round-trip to SQL Server. Replace with a single query that retrieves all needed values at once.
Is This the Right Approach for You?
The Access front-end with SQL Server back-end approach is the right choice when:
- You have a significant investment in Access forms, reports, and VBA code that you do not want to rewrite
- Your primary problems are data corruption, multi-user conflicts, and performance — not the Access user interface itself
- Your team knows Access well but is not ready to learn a new development platform
- You need a quick improvement without a complete application rewrite
It is not the right choice when:
- You need web or mobile access to the database
- Your Access application has fundamental design problems beyond the database engine
- You are planning to move away from Access entirely in the near future — in that case, the upsizing effort may be wasted
For many organizations, this split architecture buys years of reliable service while they plan a longer-term strategy. The data is safe in SQL Server, the users keep the interface they know, and the most painful Access problems go away immediately.