操作必须使用可更新查询。(错误 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 起,所有与汇总数据的 SQL 语句连接的查询都将不可更新。您没有使用连接,但 WHERE 子句完全等同于连接,因此,Jet 查询优化器对它的处理方式与对连接的处理方式相同。

如果没有临时表,恐怕你就没戏了,不过也许比我更了解 Jet SQL 的人能想出解决方法。

顺便说一下,在 Jet 3.5(Access 97)中可能是可更新的,因为当时有很多查询是可更新的,升级到 Jet 4 后就变成不可更新了。

--

评论(4)

问题肯定与使用(本例中)max() 函数有关。在连接过程中使用的任何聚合函数(例如,从连接表中检索最大值、最小值或平均值)都会导致错误。同样的情况也适用于使用子查询代替连接(如原始代码)。

这让人非常恼火(而且毫无道理!),因为这是很常见的事情。我还不得不使用临时表来解决这个问题(用插入语句将聚合值拉入临时表,然后用更新连接到该表,然后删除临时表)。

格伦

评论(0)

从本质上讲,虽然您的 SQL 看起来非常合理,但 Jet 从不支持 SQL 标准的 "更新 "语法。相反,它使用自己专有的语法(与 SQL Server 专有的 "UPDATE "语法又有所不同),这种语法**非常有限。通常,唯一的变通办法 "操作必须使用可更新查询"是非常痛苦的。请认真考虑改用功能更强的 SQL 产品。

有关您的具体问题和一些可能的解决方法,请参阅 基于总数的更新查询失败

评论(0)