1

我有以下查询(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);

使用的表格是:

4

3 回答 3

3

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

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

这篇文章帮助我了解了具体情况并提供了解决方法: http ://www.fmsinc.com/MicrosoftAccess/query/non-updateable/index.html

于 2012-10-09T15:21:19.840 回答
1

您不能SUM在更新查询中使用聚合函数(如 )。请参阅为什么我的查询是只读的?获取将导致您的查询“不可更新”的条件的完整列表。

于 2012-06-04T18:12:34.430 回答
1

Access db 引擎包括对域函数(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 语句的精力。

于 2012-06-04T19:26:42.847 回答