操作必须使用可更新的查询。 (错误3073)Microsoft Access

时间:2008-10-04 16:08:05

标签: ms-access

在某些Microsoft Access查询中,我收到以下消息:操作必须使用可更新的查询。 (错误3073)。我通过使用临时表来解决它,但我想知道是否有更好的方法。涉及的所有表都有一个主键。这是代码:

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;

22 个答案:

答案 0 :(得分:23)

从Jet 4开始,所有连接到汇总数据的SQL语句的查询都是不可更新的。您没有使用JOIN,但WHERE子句完全等同于连接,因此,Jet查询优化器将其视为处理连接的方式。

我担心没有临时表会让你失去运气,不过可能有一些人拥有更强的Jet SQL知识而不是我可以提出解决方法。

顺便说一下,它可能在Jet 3.5(Access 97)中可以更新,因为很多查询都是可更新的,然后在升级到Jet 4时变得不可更新。

-

答案 1 :(得分:7)

我遇到类似的问题,以下查询不起作用;

update tbl_Lot_Valuation_Details as LVD
set LVD.LGAName = (select LGA.LGA_NAME from tbl_Prop_LGA as LGA where LGA.LGA_CODE = LVD.LGCode)
where LVD.LGAName is null;

update tbl_LOT_VALUATION_DETAILS inner join tbl_prop_LGA on tbl_LOT_VALUATION_DETAILS.LGCode = tbl_prop_LGA.LGA_CODE 
set tbl_LOT_VALUATION_DETAILS.LGAName = [tbl_Prop_LGA].[LGA_NAME]
where tbl_LOT_VALUATION_DETAILS.LGAName is null;

然而,使用DLookup解决了这个问题;

update tbl_Lot_Valuation_Details as LVD
set LVD.LGAName = dlookup("LGA_NAME", "tbl_Prop_LGA", "LGA_CODE="+LVD.LGCode)
where LVD.LGAName is null;

此解决方案最初是在https://stackoverflow.com/questions/537161/sql-update-woes-in-ms-access-operation-must-use-an-updateable-query

提出的

答案 2 :(得分:4)

该问题与使用(在这种情况下)max()函数有关。在连接期间使用的任何聚合函数(例如,从连接表中检索max或min或avg值)都将导致错误。这同样适用于使用子查询而不是连接(如原始代码中所示)。

这非常令人讨厌(并且没有道理!),因为这是一件相当普遍的事情。我还必须使用临时表来解决它(使用insert语句将聚合值拉入临时表,然后使用您的更新连接到此表,然后删除临时表)。

格伦

答案 3 :(得分:4)

代码中没有错误。但由于以下原因,错误被抛出。

 - Please check weather you have given Read-write permission to MS-Access database file.

 - The Database file where it is stored (say in Folder1) is read-only..? 

假设您将数据库(MS-Access文件)存储在只读文件夹中,而在运行应用程序时,连接不会强制完全打开。因此,更改文件权限/其包含文件夹权限,如C:\Program files所有所有c驱动器文件都设置为只读,因此更改此权限可解决此问题。

答案 4 :(得分:3)

我知道我的答案已经晚了7年,但无论如何,这是我的建议:

当Access抱怨包含JOIN的UPDATE查询时,只需保存查询,RecordsetType属性设置为Dynaset (Inconsistent Updates)

这有时会允许UPDATE工作。

答案 5 :(得分:2)

我会尝试在Access中构建UPDATE查询。我有一个我自己写的UPDATE查询

UPDATE TABLE1
SET Field1 = 
(SELECT Table2.Field2
 FROM Table2
 WHERE Table2.UniqueIDColumn = Table1.UniqueIDColumn)

查询给了我你看到的错误。这虽然适用于我的SQL Server,但就像前面提到的答案一样,Access UPDATE语法不是标准语法。但是,当我使用Access的查询向导(它使用JOIN语法)重建它时,它工作正常。通常我只是使UPDATE查询成为使用非JET语法的直通,但我加入的其中一个表是本地Access表。

答案 6 :(得分:2)

当没有更新的表的唯一MS-ACCESS键时会发生这种情况。 (无论SQL架构如何)。

创建SQL表的MS-Access链接时,系统会要求您在链接时指定索引(键)。如果这样做不正确,或者根本没有,则对链接表的查询不可更新

将SQL表链接到Access时确保当Access提示您输入索引(键)时,您正好使用SQL用来避免问题,尽管指定任何唯一键都是Access需要更新表。 / p>

如果您不是最初链接该表的人,请从MS-ACCESS中删除链接表(该链接仅被删除)并重新链接它,正确指定密钥,所有这些都将正常工作。

答案 7 :(得分:1)

(派对有点晚了......)

我过去解决这个问题的三种方式是:

  1. 参考打开表单上的文本框
  2. DSUM
  3. 使用DLookup

答案 8 :(得分:1)

MS Access - 在更新查询中连接表...如何使其可更新

  1. 在设计视图中打开查询
  2. 点击链接b / w tables / view
  3. 在“属性”窗口中,将“唯一记录”的值更改为“是”
  4. 将查询保存为更新查询并运行它。

答案 9 :(得分:1)

我遇到了同样的问题。

我的解决方案是首先从不可更新的查询创建一个表,然后从表到表进行更新,它可以工作。

答案 10 :(得分:1)

我的失败是一个简单的INSERT语句。通过以'以管理员身份运行访问权限启动应用程序来修复。

答案 11 :(得分:0)

我通过添加“DISTINCTROW”解决了这个问题

所以这里是

UPDATE DISTINCTROW CLOG SET CLOG.NEXTDUE 

答案 12 :(得分:0)

iDevlop上面给出的答案对我有用。请注意,我无法在更新查询中找到RecordsetType属性。但是,通过将查询更改为选择查询,将该属性设置为iDevlop注释,然后将查询更改为更新查询,我能够找到该属性。这很有效,不需要临时表。

我喜欢这个只是对iDevlop发布的内容的评论,以便它从他的解决方案中流出,但我没有足够高的分数。

答案 13 :(得分:0)

检查您的数据库(数据库权限)并授予完全权限

转到DB文件夹 - &gt;右键单击属性 - >安全性 - >编辑 - &gt;完全控制  &安培;开始菜单 - &gt;运行 - &gt;输入&#34; uac&#34;把它压低(如果它很高)

答案 14 :(得分:0)

进一步回答DRUA在他/她的回答中提到的内容......

我在Access 2007中开发我的数据库。我的用户正在使用access 2007运行时。他们具有对database_Front(前端)文件夹的读取权限,以及对database_Back文件夹的读/写权限。

在推出新数据库时,用户没有按照将前端复制到计算机的完整说明进行操作,而是创建了一个快捷方式。通过快捷方式运行前端将创建一个条件,由于文件写入限制,查询不可更新。

将前端复制到文档文件夹可以解决问题。

是的,当用户必须获得前端的更新版本时,它会使事情变得复杂,但至少查询无需借助临时表等。

答案 15 :(得分:0)

您始终可以在VBA中编写类似更新的代码。我也有这个问题,我的解决方法是使用所有连接进行选择查询,其中包含我正在寻找的所有数据都能够更新,使得记录集和重复运行更新查询作为更新查询只有更新表,只搜索您正在寻找的标准

    Dim updatingItems As Recordset
    Dim clientName As String
    Dim tableID As String
    Set updatingItems = CurrentDb.OpenRecordset("*insert SELECT SQL here*");", dbOpenDynaset)
    Do Until updatingItems .EOF
        clientName = updatingItems .Fields("strName")
        tableID = updatingItems .Fields("ID")
        DoCmd.RunSQL "UPDATE *ONLY TABLE TO UPDATE* SET *TABLE*.strClientName= '" & clientName & "' WHERE (((*TABLE*.ID)=" & tableID & "))"
        updatingItems.MoveNext
    Loop

我每天只对大约60条记录执行此操作,由于查询从头到尾多次运行,而不是仅选择整个组并进行更改,因此将其执行到几千条可能需要更长时间。你可能需要围绕tableID的引号,因为它是一个字符串,但我很确定这对我有用。

答案 16 :(得分:0)

这里还有另一种情况可以适用。对于仍在使用它的任何人,在“视图”选项或“检出”中未获得“Writeablity”的文件已从Visual Source Safe检出,也会收到此错误消息。

解决方案是从Source Safe重新获取文件并应用可写性设置。

答案 17 :(得分:0)

今天在我的MS-Access 2003中使用指向带有sa密码的SQL Server 2000的ODBC tabla给了我同样的错误。
我在SQL Server数据库的表上定义了一个主键,问题就消失了。

答案 18 :(得分:0)

当我收到此错误时,可能是因为我的UPDATE语法错误,但在我修复更新查询后,我再次遇到同样的错误...所以我去了ODBC Data Source Administrator并发现了我的连接是只读的。在我连接读写并重新连接后,它工作得很好。

答案 19 :(得分:0)

我一直收到相同的错误,但所有SQL都在Access 中执行

当我修改了AccessFile的权限时。

问题已解决!!

我提供'网络服务'帐户完全控制权限,此帐户是否适用于 IIS

答案 20 :(得分:0)

我一直得到同样的错误,直到我在两个连接表中使连接字段成为唯一索引。只有这样,查询才会变得可更新。

Philip Stilianos

答案 21 :(得分:0)

从本质上讲,虽然您的SQL看起来非常合理,但Jet从未支持UPDATE的SQL标准语法。相反,它使用自己的专有语法(与SQL Server的专有UPDATE语法不同),非常有限。通常,唯一的解决方法“操作必须使用可更新的查询”非常痛苦。认真考虑切换到功能更强大的SQL产品。

有关您的具体问题和一些可能的解决方法的更多详细信息,请参阅Update Query Based on Totals Query Fails