Expert guide
#Deleted in Access Linked Tables (SQL Server): Causes and Fixes
The rows are usually still there. Access just cannot find them by their key.
Call us at +1 (385) 386-3860
Short answer: #Deleted appears when Access cannot re-locate a SQL Server row by the key it uses. Give every linked table a primary key of an exact type (int or bigint identity, not float or imprecise datetime), enable BigInt support and relink, define a unique index when linking views, add a rowversion column to edited tables, and stop triggers from changing keys. The data is almost never actually gone. These fixes are part of every Access to SQL Server migration we deliver.
Rows full of #Deleted in a datasheet look alarming, especially right after moving tables to SQL Server. In nearly every case nothing has been deleted. Access works with linked tables by fetching keys first and then the rows that belong to them. When the key it holds no longer matches anything it can find on the server, it marks the row as deleted.
How Access Tracks Linked Rows
For a linked ODBC table, Access uses the primary key, or the unique index chosen at link time, as a bookmark. It fetches a list of keys, then requests rows by those keys as you scroll. After you save a new record, it asks the server for the new row by its key. Any mismatch in that round trip produces #Deleted.
Causes and Fixes
| Cause | What happens | Fix |
|---|---|---|
| No primary key on the SQL table | Access cannot identify rows; table may be read-only or show #Deleted | Add an identity primary key; relink |
| Float / real key | Rounding makes the key value differ slightly | Use int, bigint or decimal keys |
| datetime2 or datetime key with fractions | Precision lost in transfer | Avoid date keys; add an identity key |
| bigint without BigInt support | Key treated as text in older setups | Enable BigInt support in options and relink |
| Linked view without unique index | Access guesses or cannot track rows | Choose a unique identifier when linking, or create a unique index on the linked view |
| Triggers changing the key or identity | Access looks for the wrong new row after insert | Do not change keys in triggers; use SCOPE_IDENTITY in trigger logic |
| Default values computed on the server | Key not known to Access at save time | Let the identity generate the key; avoid computed keys |
Fixing Linked Views
-- Run in Access (SQL view of a query, or CurrentDb.Execute) after linking the view. -- This creates a local "pseudo index" that tells Access which fields are unique. CREATE UNIQUE INDEX ixPK ON [dbo_vwOpenOrders] (OrderID);
The index is stored in the Access front end, not on SQL Server. If you relink the view by deleting and recreating the link, recreate the index too; a relink routine can do it automatically.
Add a rowversion Column
ALTER TABLE dbo.Orders ADD RowVer rowversion;
With a rowversion (timestamp) column, Access checks a single value to detect whether a row changed, instead of comparing every field. That reduces write conflicts and some #Deleted and "record has been changed by another user" problems, especially on tables with floating-point or long text columns. Relink after adding it.
Triggers and Identity
If an insert trigger writes into another table that has its own identity column, older patterns relying on @@IDENTITY may return the wrong value.
Inside your own server code, use SCOPE_IDENTITY() for the identity created in the current scope.
Never update the primary key of the inserted row inside a trigger.
Test by inserting through the Access form and confirming the new row displays immediately, not as #Deleted.
Enable BigInt Support
File → Options → Current Database → Data Type Support Options → tick Support Bigint Data Type for Linked/Imported Tables.
Relink all affected tables.
Note: once enabled, older Access versions without Large Number support cannot open the file.
Quick Diagnostic Steps
Open the SQL table in SSMS: does it have a primary key, and what type is it?
In Access, open the linked table in Design View: is a key shown?
Does #Deleted appear on open, or only after inserting? On insert points to identity or trigger issues.
Is the object a view? Check for a unique index on the linked view.
Do the rows reappear after closing and reopening? Then it is a key-tracking problem, not data loss.
If saves also fail with "ODBC--call failed", read ODBC--call failed in Access. Keeping links consistent across PCs is covered in relinking Access tables with VBA, and planning a migration that avoids these problems in AI-assisted Access to SQL Server migration.
FAQ
#Deleted in linked tables FAQ
Keys, views, triggers and BigInt