代码之家  ›  专栏  ›  技术社区  ›  Knox

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

  •  21
  • Knox  · 技术社区  · 16 年前

    在某些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;
    
    21 回复  |  直到 8 年前
        1
  •  23
  •   Anirudh Ramanathan    12 年前

    自Jet4以来,所有与汇总数据的SQL语句有联接的查询都是不可更新的。您没有使用join,但是where子句完全等同于join,因此,jet查询优化器对待join的方式与对待join的方式相同。

    恐怕没有临时表你就走运了,不过也许有人比我更了解Jet SQL,所以我无法想出一个解决方法。

    顺便说一句,它可能在Jet3.5(Access97)中是可更新的,因为很多查询都是可更新的,当升级到Jet4时,这些查询就变得不可更新了。

    ——

        2
  •  7
  •   Community T.Woody    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

        3
  •  4
  •   Glenn M    16 年前

    这个问题与max()函数的使用(在本例中)有明确的关系。在联接期间使用的任何聚合函数(例如,从联接表中检索max、min或avg值)都会导致错误。这同样适用于使用子查询而不是联接(如原始代码)。

    这真是令人讨厌(而且毫无道理!)因为这是一件很平常的事情。我还必须使用临时表来绕过它(使用insert语句将聚合值拉入临时表,然后使用更新连接到该表,然后删除临时表)。

    格伦

        4
  •  4
  •   Rahul Uttarkar    11 年前

    代码中没有错误。但由于以下原因引发了错误。

     - 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驱动器文件都已设置 只读的 所以更改这个权限就解决了这个问题。

        5
  •  3
  •   iDevlop    9 年前

    我知道我的答案迟了7年,但我的建议是:

    当Access抱怨包含联接的更新查询时,只需保存查询, RecordsetType 属性设置为 Dynaset (Inconsistent Updates) .

    这有时会允许更新工作。

        6
  •  2
  •   StoneJedi    13 年前

    我将尝试在Access中构建更新查询。我写了一个更新查询

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

    查询给了我您看到的那个错误。不过,这在我的SQL Server上有效,但正如前面提到的答案,访问更新语法不是标准语法。但是,当我使用Access的查询向导(它使用了连接语法)重新构建它时,它工作得很好。通常,我只是将更新查询作为使用非jet语法的传递,但我加入的表之一是本地访问表。

        7
  •  2
  •   Dave Nilson    12 年前

    当要更新的表没有唯一的MS-ACCESS键时,就会发生这种情况。(不考虑SQL模式)。

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

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

    如果您不是最初链接该表的人,请从MS-Access中删除链接表(仅删除链接),然后重新链接该表,并指定正确的键,所有操作都将正常进行。

        8
  •  1
  •   mark    14 年前

    (派对有点晚了……)

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

    1. 在打开的窗体上引用文本框
    2. 迪森
    3. 查找查找
        9
  •  1
  •   marcnz    12 年前

    我也有同样的问题。

    我的解决方案是首先从不可更新的查询中创建一个表,然后从一个表更新到另一个表,这样就可以工作了。

        10
  •  1
  •   nspire    10 年前

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

        11
  •  1
  •   Paul Dungan    9 年前

    MS Access-正在更新查询中加入表…如何使其可更新

    1. 在设计视图中打开查询
    2. 单击链接b/w tables/view一次
    3. 在__properties_窗口中,将__unique records_157;的值更改为__yes_157;
    4. 将查询另存为更新查询并运行它。
        12
  •  0
  •   Philip Stilianos    16 年前

    在将连接字段作为两个连接表中的唯一索引之前,我一直都会得到相同的错误。直到那时,查询才变得可更新。

    菲利普·斯蒂利亚诺

        13
  •  0
  •   onedaywhen    13 年前

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

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

        14
  •  0
  •   Scott 混合理论 Alex F    12 年前

    我一直得到相同的错误,但所有的sql都在access中执行。 很好 .

    当我修改 许可 访问文件。

    问题解决了!!

    我给 网络服务 '帐户完全控制权限,如果 伊斯

        15
  •  0
  •   leeand00    12 年前

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

        16
  •  0
  •   S.L. Barth is on codidact.com Monika Restecka    12 年前

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

        17
  •  0
  •   htm11h    12 年前

    这里还有另一个适用的场景。对于仍在使用Visual Source Safe的任何人而言,从Visual Source Safe中签出的文件(无论是在“视图”选项中还是在“签出”中都没有提供“可写性”)也将收到此错误消息。

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

        18
  •  0
  •   RunningWithScissors    10 年前

    为了进一步回答德鲁在他/她的回答中提到的问题…

    我在Access2007中开发了我的数据库。我的用户正在使用Access 2007运行时。它们对数据库前端文件夹具有读取权限,对数据库后端文件夹具有读取/写入权限。

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

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

    是的,当用户必须获得前端的更新版本时,这会使事情复杂化,但至少查询可以在不使用临时表等的情况下工作。

        19
  •  0
  •   Manoj essl    10 年前

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

    转到数据库文件夹->右键单击属性->安全->编辑->授予完全控制权 &开始菜单->运行->键入“UAC”使其关闭(如果高)

        20
  •  0
  •   marc_s HarisH Sharma    9 年前

    您总是可以用类似更新的VBA编写代码。我也遇到了这个问题,我的解决方法是使用所有联接进行一个select查询,其中包含我要更新的所有数据,生成一个记录集,并将更新查询重复地作为只更新表的更新查询运行,只搜索您要查找的条件。

        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的引号周围加上“”,因为它是一个字符串,但我确信这对我很有用。

        21
  •  0
  •   Sue White    8 年前

    上面IDevlop给出的答案对我很有用。注意,我在更新查询中找不到recordsettype属性。但是,通过将查询更改为select查询,将该属性设置为idevlop所指出的值,然后将查询更改为更新查询,我能够找到该属性。这很有效,不需要临时表。

    我希望这只是对IDevlop发表的内容的评论,以便从他的解决方案中得出结论,但我没有足够高的分数。