2

我写了这个查询:

UPDATE tbl_stock1 SET 
tbl_stock1.weight1 = (
    select (b.weight1 - c.weight_in_gram) as temp 
    from
        tbl_stock1 as b,
        tbl_sales_item as c 
    where
        b.item_submodel_id = c.item_submodel_id 
        and b.item_submodel_id = tbl_stock1.item_submodel_id 
        and b.status <> 'D' 
        and c.status <> 'D'
    ), 
tbl_stock1.qty1 = (
    select (b.qty1 - c.qty) as temp1 
    from
        tbl_stock1 as b,
        tbl_sales_item as c 
    where 
        b.item_submodel_id = c.item_submodel_id 
        and b.item_submodel_id = tbl_stock1.item_submodel_id 
        and b.status <> 'D' 
        and c.status <> 'D'
    )
WHERE
    tbl_stock1.item_submodel_id = 'ISUBM/1' 
    and tbl_stock1.status <> 'D';

我收到此错误消息:

Operation must use an updatable query. (Error 3073) Microsoft Access

但是如果我在 SQL Server 中运行相同的查询,它将被执行。

谢谢,点菜

4

6 回答 6

2

考虑这个使用 Northwind 的非常简单的 UPDATE 语句:

UPDATE Categories
   SET Description = (
                      SELECT DISTINCT 'Anything' 
                        FROM Employees
                     );

它失败并显示错误“操作必须使用可更新查询”。

Access 数据库引擎 simple 不支持在SET子句中使用标量子查询的 SQL-92 语法。

Access 数据库引擎有自己的专有UPDATE..JOIN..SET语法,但不安全,因为与标量子查询不同,它不需要值是明确的。如果值不明确,那么引擎会无声地“选择”一个任意值,即使您知道问题,也很难(如果不是不可能)预测将应用哪个值。

例如,考虑CategoriesNorthwind 中的现有表和以下 daft(非)表作为更新的目标(daft 但很简单,可以清楚地说明问题):

CREATE TABLE BadCategories
(
 CategoryID INTEGER NOT NULL, 
 CategoryName NVARCHAR(15) NOT NULL
)
;
INSERT INTO BadCategories (CategoryID, CategoryName) 
   VALUES (1, 'This one...?')
;
INSERT INTO BadCategories (CategoryID, CategoryName) 
   VALUES (1, '...or this one?')
;

现在为UPDATE

UPDATE Categories 
       INNER JOIN (
                   SELECT T1.CategoryID, T1.CategoryName
                     FROM Categories AS T1
                   UNION ALL 
                   SELECT 9 - T2.CategoryID, T2.CategoryName
                     FROM Categories AS T2
                  ) AS DT1
       ON DT1.CategoryID = Categories.CategoryID
   SET Categories.CategoryName = DT1.CategoryName;

当我运行它时,我被告知有两行已更新,这很有趣,因为类别表中只有一个匹配的行。结果是现在的CategoriesCategoryID有“......还是这个?” 价值。我怀疑这是一场竞赛,看哪个值最后写入表。

SET当和/或 WHERE 子句与' 子句匹配时,SQL-92 标量子查询是冗长的,SET但至少它消除了歧义(加上一个体面的优化器应该能够检测到子查询是紧密匹配的)。引入的 SQL-99 标准MERGE可用于消除上述重复,但不用说 Access 也不支持。

Access 数据库引擎缺乏对 SQL-92 标量子查询语法的支持,这对我来说是它最糟糕的“设计特性”(阅读“错误”)。

另请注意,Access 数据库引擎的专有UPDATE..JOIN..SET语法无论如何都不能与集合函数一起使用(Access 中的“总计查询”)。请参阅基于总计查询失败的更新查询

于 2009-08-06T11:35:07.200 回答
2

我很确定 JET DB 引擎将任何带有子查询的查询视为不可更新。这很可能是错误的原因,因此,您需要重新编写逻辑并避免子查询。

作为测试,您还可以尝试删除在两个子查询中执行的计算(减法)。这个计算可能也不能很好地与更新一起使用。

于 2009-08-05T06:04:46.810 回答
1

请记住,如果您复制最初将查询或摘要查询作为查询的一部分的查询,即使您删除了这些查询并且只有链接表,该查询也会(错误地)表现得像它仍然具有不可更新的字段并会给你这个错误。您只需根据需要重新创建查询,但这是一个阴险的小故障。

于 2018-03-01T18:08:12.843 回答
0

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

  • 请检查您是否已授予 MS-Access 数据库文件的读写权限。
  • 存储它的数据库文件(比如在 Folder1 中)是只读的..?

假设您将数据库(MS-Access 文件)存储在只读文件夹中,而在运行您的应用程序时,连接并未强制完全打开。因此,更改文件权限/其包含文件夹权限,就像在C:\Program files所有大多数 C 驱动器文件中设置为只读一样,因此更改此权限可以解决此问题。

于 2013-12-06T09:57:58.100 回答
0

您正在更新weight1qty1值,而这些值又来自weight1qty1(分别)。这就是为什么 MS-Access 对更新感到窒息。它可能还在后台进行了一些优化。

我解决这个问题的方法是将计算转储到临时表中,然后从临时表中更新第一个表。

于 2009-08-05T14:43:24.270 回答
-1

在查询属性中,尝试将 Recordset Type 更改为Dynaset (Inconsistent Updates)

于 2009-08-05T07:39:44.153 回答