使用Access提升余额的SQL更新查询“操作必须使用可更新的查询”

时间:2012-06-04 16:56:36

标签: ms-access ms-access-2010

我有以下查询(MS Access 2010),我正在尝试使用它来更新具有运行余额的表:

UPDATE Accounts a SET a.CurrentBalance = 
(SELECT sum(iif(c.categoryid = 2,t.Amount * -1, t.Amount)) + 
        (select a1.openingbalance 
         from accounts a1 where a1.accountid = a.accountid) AS TotalAmount
FROM transactions t inner join (
     transactiontypes tt inner join 
     categories c on c.categoryid = tt.categoryid) 
     on t.transactiontypeid = tt.transactiontypeid);

使用的表是:

3 个答案:

答案 0 :(得分:3)

解决“查询必须使用可更新查询”的方法是使用临时表,然后根据临时表中的聚合数据更新最终目标数据。在你的情况下,正如mwolfe建议的那样,你在内部选择查询中有一个聚合函数。对于我来说,解决方法可以快速解决这种情况。

参考:http://support.microsoft.com/kb/328828

本文帮助我了解情况的具体情况并提供了相关的工作: http://www.fmsinc.com/MicrosoftAccess/query/non-updateable/index.html

答案 1 :(得分:1)

您不能在更新查询中使用聚合函数(如SUM)。请参阅Why is my query read-only?以获取将导致您的查询“不可更新”的完整条件列表。

答案 2 :(得分:1)

Access数据库引擎包括对域功能(DMax,DSum,DLookup等)的支持。域功能通常可以让您绕过不可更新的查询问题。

DSum()中使用这3行数据考虑MyTable

id MyNumber
 1        2
 2        3
 3        5

然后在立即窗口中,这里有2个样本DSum()表达式。

? DSum("MyNumber", "MyTable")
 10 

? DSum("IIf(id=1,MyNumber * -1, MyNumber)", "MyTable")
 6 

我认为您可以使用类似第二个表达式的内容来替换查询的sum(iif(c.categoryid = 2,t.Amount * -1, t.Amount)部分。

也许您可以使用DLookup()表达式来获取TotalAmount值。不幸的是,我试图将您当前的SQL转换为域函数感到沮丧。我意识到这不是一个完整的解决方案,但希望它能为您指出一些有用的东西。如果您编辑问题以向我们展示起始数据的简要样本以及您希望根据该样本数据从UPDATE语句中获得的内容,我愿意再看一下。

最后,考虑一下您是否必须将CurrentBalance存储在表格中。根据经验,避免存储派生值。而是使用SELECT查询在需要时计算派生值。这种方法可以保证CurrentBalance在您检索时始终保持最新状态。它还可以省去创建工作UPDATE语句的工作。