tags:

views:

10836

answers:

6

On some Microsoft Access queries, I get the following message: Operation must use an updatable query. (Error 3073). I work around it by using temporary tables, but I'm wondering if there's a better way. All the tables involved have a primary key. Here's the code:

UPDATE CLOG SET CLOG.NEXTDUE = (
    SELECT H1.paidthru 
    FROM CTRHIST as H1
    WHERE H1.ACCT = clog.ACCT AND
    H1.SEQNO = (
        SELECT MAX(SEQNO) 
        FROM CTRHIST 
        WHERE CTRHIST.ACCT = Clog.ACCT AND 
        CTRHIST.AMTPAID > 0 AND
        CTRHIST.DATEPAID < CLOG.UPDATED_ON
    )
)
WHERE CLOG.NEXTDUE IS NULL;
+1  A: 

Since Jet 4, all queries that have a join to a SQL statement that summarizes data will be non-updatable. You aren't using a JOIN, but the WHERE clause is exactly equivalent to a join, and thus, the Jet query optimizer treats it the same way it treats a join.

I'm afraid you're out of luck without a temp table, though maybe somebody with greater Jet SQL knowledge than I can come up with a workaround.

BTW, it might have been updatable in Jet 3.5 (Access 97), as a whole lot of queries were updatable then that became non-updatable when upgraded to Jet 4.

--
David W. Fenton
David Fenton Associates

David-W-Fenton
Thanks for the explanation.
Knox
So we have a pretty trivial update statement (UPDATE CLOG SET CLOG.NEXDUE = ... WHERE CLOG.NEXTDUE IS NULL), and the only reason why it does not work is that the query used to compute new value of CLOG.NEXDUE is "too complex". Unbelievable!! I am glad we switched from Jet to SQL Server!!! :-))
Yarik
I don't believe your assertion that the SQL you quote could ever produce the "query too complex" error in Jet. You are either mistaken, or for some reason I can't fathom, spreading misinformation about Jet.
David-W-Fenton
+1  A: 

In essence, while your SQL looks perfectly reasonable, Jet has never supported the SQL standard syntax for UPDATE; instead, it uses its own proprietary syntax (different again from SQL Server's proprietary UPDATE syntax) which is VERY limited. Often, the only workarounds "Operation must use an updatable query" are very painful. Seriously consider switching to a more capable SQL product.

For some more details about your specific problems and some possible workarounds, see

[http://support.microsoft.com/default.aspx?scid=kb;en-us;116142&amp;Produc][1]

[1]: http://ACC: Update Query Based on Totals Query Fails

onedaywhen
+1  A: 

The problem defintely relates to the use of (in this case) the max() function. Any aggregation function used during a join (e.g. to retrieve the max or min or avg value from a joined table) will cause the error. And the same applies to using subqueries instead of joins (as in the original code).

This is incredibly annoying (and unjustified!) as it is a reasonably common thing to want to do. I've also had to use temp tables to get around it (pull the aggregated value into a temp table with an insert statement, then join to this table with your update, then drop the temp table).

Glenn

Glenn M
A: 

I kept getting the same error until I made the connecting field a unique index in both connecting tables. Only then did the query become updatable.

Philip Stilianos

You may wish to read this article on when queries can be update: http://msdn.microsoft.com/en-us/library/aa198446.aspx
Remou
+1  A: 

Even more maddening -- i have an update query the runs fine using linked tables from a SQL Server database. THE SAME QUERY running against an exact copy of the SAME DATABASE returns "Operation must use an updatable query" -- AARGH!

No workaround found yet.

+1  A: 

(A little late to the party...)

The three ways I've gotten around this problem in the past are:

  1. Reference a text box on an open form
  2. DSum
  3. DLookup
mark
Temp tables are often faster.
David-W-Fenton
Yep, I'm still using Temp tables. I only wish they were really temporary, but I just let them live, and the next time the make table runs, it replaces the previous "temporary" table.
Knox