操作必须使用可更新的查询。 (错误3073)Microsoft 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; 

自从Jet 4以来,所有查询都join到汇总数据的SQL语句中将是不可更新的。 您没有使用JOIN,但WHERE子句与连接完全相同,因此Jet查询优化器将其视为与对待连接的方式相同。

如果没有临时表,恐怕你运气不好,虽然也许有更多Jet SQL知识的人比我能想出一个解决方法。

顺便说一句,它可能在Jet 3.5(Access 97)中是可更新的,因为整个查询都是可更新的,那么在升级到Jet 4时就变成了不可更新的。

我有一个类似的问题,其中以下查询不起作用;

 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; 

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

这个问题明确地涉及(在这种情况下)max()函数的使用。 在连接期间使用的任何聚合函数(例如,从连接表中检索最大值或最小值或平均值)都会导致错误。 这同样适用于使用子查询而不是联接(如在原始代码中)。

这是令人难以置信的烦人(而且是不合理的!),因为这是一个相当普遍的事情要做。 我也必须使用临时表来解决这个问题(把汇总的值用insert语句拉到临时表中,然后用你的更新join到这个表中,然后删除临时表)。

格伦

代码中没有错误。 但是错误是由于以下原因而导致的。

  - 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盘文件已设置为只读,所以更改此权限解决了这个问题。

我知道我的答案迟了7年,但这里是我的build议:

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

这有时会允许更新工作。

我会尝试在Access中build立更新查询。 我有一个我自己写的UPDATE查询

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

查询给了我你看到的错误。 虽然这工作在我的SQL Server,但就像早先的答案指出的,Access UPDATE语法不是标准语法。 但是,当我使用Access的查询向导(它使用JOIN语法)重build它,它工作正常。 通常我只是使UPDATE查询passthrough使用非JET语法,但我join的表之一是本地Access表。

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

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

在将SQL表连接到Access时,请确保Access在提示您使用索引(键)时确切使用了SQL用来避免问题的任何唯一键,但所有Access都需要更新表。

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

(晚会有点晚…)

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

  1. 在打开的表格上引用一个文本框
  2. DSUM
  3. 使用DLookup

我遇到过同样的问题。

我的解决scheme是首先从不可更新的查询创build一个表,然后从表到表进行更新,它的工作原理。

我的一个简单的INSERT语句失败了。 通过以“以pipe理员身份运行”访问启动应用程序来修复。

MS Access – 在更新查询中连接表…如何使其更新

  1. 在devise视图中打开查询
  2. 点击链接黑/白表/视图
  3. 在“属性”窗口中,将“唯一logging”的值更改为“是”
  4. 将查询保存为更新查询并运行它。

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

菲利普Stilianos

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

有关您的特定问题和一些可能的解决方法的更多详细信息,请参阅更新查询基于总计查询失败 。

我不断得到相同的错误,但所有SQL在Access中执行得很好

当我修改AccessFile的权限

问题修复了!

我给' networking服务 '帐户完全控制权限,这个帐户如果为IIS

当我得到这个错误时,可能是因为我的UPDATE语法错误,但是在我修复了更新查询之后,我又得到了同样的错误…所以我去了ODBC Data Source Administrator ,发现我的连接被读取-只要。 在我连接读写和重新连接后,它工作得很好。

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

这里还有另一种情况会适用。 一个被Visual Source Safe检出的文件,对于任何仍在使用它的人,在View选项或Check Out中都没有被赋予“Writeablity”,也会收到这个错误信息。

解决scheme是重新从源安全文件获取文件并应用可写性设置。

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

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

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

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

是的,当用户必须获得前端的更新版本时,这会使事情变得复杂,但至less查询的工作原理不会诉诸临时表等。

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

进入数据库文件夹 – >右键属性 – >安全 – >编辑 – >完全控制和开始菜单 – >运行 – >键入“UAC”把它closures(如果它高)

您可以随时在VBA中编写类似更新的代码。 我也有这个问题,我的解决方法是做一个select查询,所有的连接,所有的数据,我正在寻找可以更新,使一个logging集和重复运行更新查询作为更新查询只有更新表,只search你正在寻找的标准

  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条logging,做到几千条可能需要更长的时间,因为查询从头到尾多次运行,而不是仅仅select一个整体组并进行更改。 你可能需要在tableID的引号周围,因为它是一个string,但我很确定这是对我有用的。

iDevlop上面给出的答案为我工作。 请注意,我无法在我的更新查询中findRecordsetType属性。 但是,我能够通过更改我的查询select查询find该属性,将该属性设置为iDevlop指出,然后将我的查询更改为更新查询。 这工作,不需要临时表。

我希望这个只是iDevlop发布的评论,以便它从他的解决schemestream出,但我没有足够高的分数。