我写了这个查询:
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中运行相同的查询,它将被执行。
谢谢, 迪内希
答案 0 :(得分:2)
我非常确定JET数据库引擎将子查询视为不可更新的任何查询。这很可能是错误的原因,因此,您需要重新编写逻辑并避免子查询。
作为测试,您可能还会尝试删除在两个子查询中执行的计算(减法)。这个计算也可能不适合更新。
答案 1 :(得分:2)
使用Northwind考虑这个非常简单的UPDATE语句:
UPDATE Categories
SET Description = (
SELECT DISTINCT 'Anything'
FROM Employees
);
失败并显示错误'操作必须使用可更新的查询'。
Access数据库引擎simple不支持使用SET
子句中的标量子查询的SQL-92语法。
Access数据库引擎具有自己的专有UPDATE..JOIN..SET
语法但不安全,因为与标量子查询不同,它不需要值明确。如果值不明确,则引擎静默“随意”选择一个,即使您意识到问题,也很难(如果不是不可能的话)预测将应用哪一个。
例如,考虑Northwind中现有的Categories
表和下面的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;
当我运行这个时,我被告知已经更新了两行,这很有趣,因为在Categories表中只有一个匹配的行。结果是Categories
表CategoryID
现在有'...或者这个?'值。我怀疑最近看到哪个值被写入表中是一场竞赛。
当SET
中有多个子句和/或WHERE子句与SET
的子句匹配时,SQL-92标量子查询是详细的,但至少它消除了歧义(加上一个不错的优化器)应该能够检测到子查询是否匹配)。 SQL-99标准引入了MERGE
,它可用于消除上述重复,但不用说Access也不支持。
Access数据库引擎缺乏对SQL-92标量子查询语法的支持对我来说是最糟糕的“设计特性”(读作“bug”)。
另请注意,Access数据库引擎的专有UPDATE..JOIN..SET
语法无论如何都不能与set函数一起使用(Access-speak中的'totals queries')。请参阅Update Query Based on Totals Query Fails。
答案 2 :(得分:1)
请记住,如果您复制最初在查询中包含查询或摘要查询的查询,即使您删除了这些查询并且只有链接表,查询也会(错误地)表现得像它仍然具有非-updateable字段,会给你这个错误。您只需根据需要重新创建查询,但这是一个阴险的小故障。
答案 3 :(得分:0)
您正在使用weight1
和qty1
(分别)派生的值更新weight1
和qty1
。这就是为什么MS-Access对更新感到窒息的原因。它可能也在后台做了一些优化。
我解决这个问题的方法是将计算转储到临时表中,然后从临时表中更新第一个表。
答案 4 :(得分:0)
代码中没有错误。但由于以下原因,错误被抛出。
假设您将数据库(MS-Access文件)存储在只读文件夹中,而在运行应用程序时,连接不会强制完全打开。因此,更改文件权限/其包含文件夹权限,如C:\Program files
所有所有c驱动器文件都设置为只读,因此更改此权限可解决此问题。
答案 5 :(得分:-1)
在查询属性中,尝试将Recordset类型更改为动态集(不一致的更新)