SQL Update woes in MS Access - Operation must use an updateable query

67,828

Solution 1

A subquery of (SELECT ID FROM t2) can't work unless there is only one record in t2. Which ID are you expecting to be used?

The error message that is being reported normally occurs when you have joins and are not including all of the primary keys necessary to update back to tables in a data bound form (for example, your original DISTINCT destroys information about keys, so if it was bound to a form, the form would not be able to save back).

The fact you are using DISTINCT there would make me suspicious that the sub query is returning more than one row in your more complex example. This is probably the most common problem with assigning out of a sub query result: under-constraining the where clause.

Another problem I have seen with assigning out of a subquery is if the syntax of the inner query is incorrect. At least with SQL 2000 and 2005 back ends, the query processor will silently fail and return NULL in such cases. (This is, as far as I can tell, a bug: I see no reason why something that will return an error at the top level would be silently permitted in a subquery... but there it is.)

EDIT: Just to ensure that neither Paul or I wasn't going crazy, I created the following tables:

t1 | ID, FK, Data
t2 | ID2, Data2

I did not put any constraints except a primary key on ID and ID2. All fields were text, which is different from what I normally use for IDs, but should be irrelevant.

t1:

ID  FK  Data
Key1        Data1
Key2        Data2
Key3        Data3

t2:

ID2 Data2
Key1    DataA
Key2    DataB
Key3    DataC

A query of the form:

UPDATE t1 SET t1.FK = (select ID2 from t2 where t2.ID2 = t1.ID);

Failed with the same message Paul got.

select *, (select ID2 from t2 where t2.ID2 = t1.ID) as foreign from t1, 

works as expected, so we know the subquery syntax is not to blame.

UPDATE t1 SET t1.FK = 'Key1'

also works as expected, so we don't have a corrupt or non updateable destination.

Note: if I change the database backend from native to SQL 2005, the update works! A bit of googling around, and I find Access MVPs suggesting DLOOKUP to replace a subquery:

http://www.eggheadcafe.com/software/aspnet/31849054/update-with-subquerycomp.aspx

Apparently this is a bug in Access SQL, one that is avoided when using a SQL Express 2000 or higher back end. (The google results for "access update subquery" support this theory).

See here for how to use this workaround: http://www.techonthenet.com/access/functions/domain/dlookup.php

Solution 2

I have to weigh in with David W. Fenton's comment on the OP.

This is highly annoying problem with Jet/ACE. But try either:

  1. go to the query properties (click the background of the pane where the tables are displayed) and set 'Unique Records' to 'Yes'
  2. Option 1 is the equivalent of adding the somewhat strange looking DISTINCTROW keyword to the SELECT clause, eg

:

UPDATE DISTINCTROW tblClient 
       INNER JOIN qryICMSClientCMFinite 
          ON tblClient.ClientID = qryICMSClientCMFinite.ClientID
   SET tblClient.ClientCMType = "F";

This solves so many problems involving this error message that it is almost ridiculous.

That's MS Access in a nutshell - if you don't know the trade-secret workaround for problem x, you can take days trying to find the answer. To know the 10,000 workarounds IS to program Access. Is that enough of a warning for the uninitiated ?

Ben

Solution 3

This worked for me (Access 2000)

UPDATE DISTINCTROW T1 inner join T2 on T2.f1 = T1.f1  SET f2 = f2;

Solution 4

I havent't read the whole thread, but this is the solution that I am using:

update (select * from t1 inner join t2 on t1.key = t2.key) set t1.field1 = t2.field2

and that works fine in MS Access for me.

Solution 5

My solution was to change my sql on that way.

  update (select o.pricein, g.pricein from operations o left join goods g on g.id = o.goodid where o.opertype = 4 and o.acct = 1) 
  set o.pricein = g.pricein
Share:
67,828
Paul Smith
Author by

Paul Smith

I was a hobbyist programmer who learned about Pascal and C whilst doing my A-levels. After a degree in maths, I now work as a programmer.

Updated on December 12, 2021

Comments

  • Paul Smith
    Paul Smith over 2 years

    I have a select query which does some text manipulation to essentially reformat a field so that I can look it up in another table:

    If my first table if I have a field like "J1/2" it looks up the ID of a record in a different table with J1 and J2 in the appropriate fields.

    This all works well.

    Now I want to update the original table so I don't have to do lookups using this string manipulation anymore, but my attempts at update queries end with "Operation must use an updateable query"

    Any ideas?

    My SELECT statement:

    SELECT DISTINCT
    t1.DD,
    t1.TN,
    t1.DD & " J" & MID(t1.TN,2,1) AS CalculatedStart,
    t1.DD & " J" & MID(t1.TN,4,1) AS CalculatedEnd,
    t2.ID
    FROM t1 INNER JOIN t2
    ON (t1.DD & " J" & MID(t1.TN,2,1)=t2.StartLink)
    AND (t1.DD & " J" & MID(t1.TN,4,1)=t2.EndLink)
    WHERE t1.TN Like "J?/?"
    AND t1.DD Like "M*";
    

    Recall - this works fine and I get the necessary t2.ID out the other end.

    So I want to do something like:

    UPDATE t1 SET t2ID = (
        SELECT Query1.ID
        FROM Query1
        WHERE t1.DD=Query1.DD
        AND t1.TN=Query1.TN
        )
    WHERE t1.TN Like "J?/?"
    AND t1.DD Like "M*";
    

    Only this fails. This is within MS Access itself so I can't imagine an actual permissions problem like most of the "Operation must use an updateable query" problems seem to be.

    EDIT: Trying to simplify the case that doesn't work.

    This UPDATE query is fine:

    UPDATE t1
    SET t2ID="Unknown"
    WHERE TN LIKE "J?/?"
    AND DD LIKE "M*";
    

    This one fails (Thanks Goedke - this example obviously fails because the subquery returns more than 1 result. I had oversimplified to try to find my problem)

    UPDATE t1
    SET t2ID=(SELECT ID FROM t2)
    WHERE TN LIKE "J?/?"
    AND DD LIKE "M*";
    

    So do I just have my subquery syntax wrong in some way?

    EDIT: This SELECT statement is fine too:

    SELECT t1.OA, t1.DD, t1.TN, t1.HATRIS,
        query1.DD, query1.TN, query1.ID
    FROM t1 INNER JOIN query1
    ON t1.DD=query1.DD
    AND t1.TN=query1.TN
    

    Furthermore, using count on the select statement above shows that there is exactly 1 ID being returned per (DD,TN) combination

    EDIT:

    The simplest case I've now got to - using various SELECT statements I now have a table with just 2 columns - the primary key of t1 and the value I want to insert into t1.

    I still can't seem to write

    UPDATE t1 SET t1.f2 = (SELECT t2.f2 FROM t2 WHERE t2.f1 = t1.f1)
    

    where t1's primary key is f1. Even adding WHERE t1.f1 IN (SELECT f1 FROM t2) doesn't help. (Added to eliminate the possibility that the subquery returns 0 results)