Access query

Posted on 2013-12-02
Last Modified: 2013-12-04
I have a query in Access 2007 that uses 2 linked SQL Server tables.  Both tables have primary keys.  They are joined by the primary key fields with a left join so the field from table 2 should be blank if there are no matching records.  Instead of being blank, the fields say #Deleted (if there is a match, they show the field contents.)  If I put a sort on the primary key field of Table 1 in Design View, no change.  If, however, I right click on the blank area to bring up the Properties box and I put a sort there of the same field in the Order By and then run the query, the #Deleted goes away and becomes blank.  The sort in Design View shows up in the SQL View, the sort in Properties does not.

I need to know what the sort in Properties is fixing, because I'm putting the query into my VB code and I can't use a Properties sort there.

Any ideas?   Thanks in advance.
Question by:loybob
LVL 35

Expert Comment

ID: 39693342
I don't have an answer but I wanted to tell you that you are not alone.  I ran into that same situation and haven't figured out why.  I have other right-joins to the same table that work as expected.  But one particular join returns #Deleted#.  I'll try adding a sort to the query to see if that solves the problem.  The #Deleted# field is far enough down the sort order to not actually change the sequence of the details.
LVL 26

Expert Comment

ID: 39693351
That's a weirdy.
Now, many questions.
Do you have other units running Access?
Does the problem persist on other machines, or just one?
If you set up a query between two different tables, does the same problem occur?
They are joined on the primary key.  Is the primary key AutoNumber (yay!) or text (boo!)

If you create a postable sample by exporting the two tables to a new db (making them local tables) and creating the query, does the same problem manifest?

"I need to know what the sort in Properties is fixing, because I'm putting the query into my VB code and I can't use a Properties sort there."

You also won't be SEEING the query in code, so you don't care --so long as the values are what you expect.
So build your recordset in code
dim db as database
dim rs as recordset
dim sql as string

sql = "select * from whatever from whatever left join thatone on =;"
set db = currentdb
set rs = db.opendynaset(sql, dbopendynaset ,dbseechanges)


do until rs.eof
    msgbox nz(, "null")

Open in new window

Run the code.  Are nulls being returned when required by the left join?  or some oddball value?
LVL 32

Expert Comment

ID: 39693363
try running the query in code to recordset and do not use the dbseechanges as it's telling the engine to track changes, which I don't think you want anyways.
Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

LVL 26

Expert Comment

ID: 39693378
If you DON'T give it dbSeeChanges and it involves SQL Server linked tables the code bombs.  It's a required element with dbOpenDynaset.
If you don't want to see changes you need to open with a different option (dbOpenSnapshot etc.)

@pathartman, @loybob
What field shows the #DELETED?
Are they text fields (or maybe memo fields!)?
LVL 35

Expert Comment

ID: 39693421
I think I may have resolved my problem.  It was intermittent and I hadn't really spent any time on it since it was a query I was using for myself.  The query was joining an error code (5 character text) to a lookup table to bring back a description (255 character text).  I think the problem was caused because some of the rows had ZLS in the error code when there was no error rather than null.  I just got rid of all the ZLS this morning because they were causing a problem in a report because they were keeping the error line from shrinking when there was no error and I haven't seen #Deleted# for the description since I did that.  I don't know why ZLS would cause such a problem in a right-join or if something else fixed the problem.
LVL 35

Expert Comment

ID: 39693430
dbSeeChanges is used when a  table in the recordset has an identity column.  This allows Access to "see" the newly assigned identity column if a record is added.  It is not needed when you use a snapshot type recordset because snapshots are not updateable but it is needed when you use a dynaset since even if you have no intention of updating it, the implication is that you could.
LVL 26

Expert Comment

ID: 39693442
There's a long-in-the-tooth kb article about it here.

The Microsoft Jet database engine is designed around a keyset-driven model. This means that data is retrieved, inserted, and updated based on key values (in the case of a linked ODBC table, the unique index of a table).

 After Microsoft Access performs an insert or an update of a linked ODBC table, it uses a Where criteria to select the record again to verify the insert or update. The Where criteria is based on the unique index. Although numerous factors can cause the select not to return any records, most often the cause is that the key value Microsoft Access has cached is not the same as the actual key value on the ODBC table. Other possible causes are as follows:
•Having an update or insert trigger on the table, modifying the key value.
•Basing the unique index on a float value.
•Using a fixed-length text field that may be padded on the server with the correct amount of spaces.
•Having a linked ODBC table containing Null values in any of the fields making up the unique index.
These factors do not directly cause the "#Deleted" error message. Instead, they cause Microsoft Access to go to the next step in maintaining the key values, which is to select the record again, this time with the criteria based on all the other fields in the record. If this step returns more than one record, Microsoft Access returns the "#Deleted" message because it does not have a reliable key value to work with. If you close and re-open the table or choose Show All Records from the Records menu, the "#Deleted" errors are removed.

 Microsoft Access uses a similar process to retrieve records from an linked ODBC table. First, it retrieves the key values and then the rest of the fields that match the key values. If Microsoft Access is not able to find that value again when it tries to find the rest of the record, it assumes that the record is deleted.

The following are some strategies that you can use to avoid this behavior:
•Avoid entering records that are exactly the same except for the unique index.
•Avoid an update that triggers updates of both the unique index and another field.
•Do not use a Float field as a unique index or as part of a unique index because of the inherent rounding problems of this data type.
•Do all the updates and inserts by using SQL pass-through queries so that you know exactly what is sent to the ODBC data source.
•Retrieve records with an SQL pass-through query. An SQL pass-through query is not updateable, and therefore does not cause "#Delete" errors.
•Avoid storing Null values within any field making up the unique index of your linked ODBC table.

So for @PatHartman, the text field and it's values were the proximate cause

Author Comment

ID: 39693456
I fixed the problem myself - I created a another query from scratch, and it didn't get the #Deleted, and it's joins were in a different order than the first query - same joins but different order.  

What I'd still like to know is where the Order By from the Properties is stored and why is that different than Sort in the Design View which adds an Order By in the SQL View.
LVL 26

Accepted Solution

Nick67 earned 500 total points
ID: 39693481
It is likely stored in the LvProp field of MSysObjects.
The ORDER BY clause in SQL tells the engine how to retrieve the records when the query is run.  The Properties Order by is how just the Query Editor is going to arrange the records you see and is the equivalent of doing Records | Sort in the GUI, but then persisting that.

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article is a continuation or rather an extension from Cascading Combos ( and builds on examples developed in detail there. It should be understandable alone, but I recommend reading the previous artic…
Most if not all databases provide tools to filter data; even simple mail-merge programs might offer basic filtering capabilities. This is so important that, although Access has many built-in features to help the user in this task, developers often n…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now