我在Access中有一个名为“tempSpring_ASN”的表,其中包含以下字段(其中包括):
SHP_CUSTOM_5(自动编号)
RECORD_TYPE(文字)
PO_NUM(文字)。
我需要更改RECORD_TYPE的值,这样如果PO_NUM与前一条记录中的PO_NUM相同,则RECORD_TYPE应为“LIN”,否则(或者如果它是第一条记录),RECORD_TYPE应为“HDR”
我创建了以下查询以获取RECORD_TYPE的正确新值:
SELECT TOP 1 t1.SHP_CUSTOM_5,
t1.PO_NUM AS CurrentValue,
NULL AS PreviousValue,
"HDR" AS RECORD_TYPE
FROM tempSpring_ASN AS t1
ORDER BY t1.SHP_CUSTOM_5
UNION ALL
SELECT t1.SHP_CUSTOM_5,
t1.PO_NUM AS CurrentValue,
t2.PO_NUM AS PreviousValue,
IIf([CurrentValue]=[PreviousValue],'LIN','HDR') AS RECORD_TYPE
FROM tempSpring_ASN AS t1,
tempSpring_ASN AS t2
WHERE t1.SHP_CUSTOM_5 = t2.SHP_CUSTOM_5 + 1
ORDER BY t1.SHP_CUSTOM_5;
我已将该查询保存为“tempSpring_ASN_With_PreviousRow”。现在我正在尝试使用它来使用以下查询更新原始tempSpring_ASN表:
UPDATE tempSpring_ASN INNER JOIN tempSpring_ASN_With_PreviousRow ON tempSpring_ASN.SHP_CUSTOM_5 = tempSpring_ASN_With_PreviousRow.SHP_CUSTOM_5 SET tempSpring_ASN.RECORD_TYPE = [tempSpring_ASN_With_PreviousRow].[RECORD_TYPE];
但我得到了,“操作必须使用可更新的查询。”我不确定是不是因为我正在尝试更新连接中的一个表,或者因为我试图根据同一个表中的值更新表,或者是由于其他原因。无论如何,我正在寻找有用的东西。
谢谢!
更新(无双关语):
我尝试过以下更新查询:
UPDATE tempSpring_ASN INNER JOIN Table5 ON tempSpring_ASN.SHP_CUSTOM_5 = Table5.SHP_CUSTOM_5 SET tempSpring_ASN.RECORD_TYPE = "zzz";
它工作正常。结果是tempSpring_ASN已更新,但Table5不是。显然,如果在SQL语句中连接了两个表,即使您在一个表上运行更新,它仍然不会尝试更新连接中的另一个表。既然如此,我不确定为什么我的原始更新查询不起作用。我知道tempSpring_ASN_With_PreviousRow不可更新,因为它是一个UNION查询,但我不是尝试来更新它。相反,我正在尝试更新tempSpring_ASN - 连接中的另一个表, 可更新。
更新2: 然后我尝试使用相关子查询,如下所示:
UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
SELECT RECORD_TYPE
FROM (
SELECT TOP 1 t1.SHP_CUSTOM_5,
t1.PO_NUM AS CurrentValue,
NULL AS PreviousValue,
"HDR" AS RECORD_TYPE
FROM tempSpring_ASN AS t1
ORDER BY t1.SHP_CUSTOM_5
UNION ALL
SELECT t1.SHP_CUSTOM_5,
t1.PO_NUM AS CurrentValue,
t2.PO_NUM AS PreviousValue,
IIf([CurrentValue] = [PreviousValue], 'LIN', 'HDR') AS RECORD_TYPE
FROM tempSpring_ASN AS t1,
tempSpring_ASN AS t2
WHERE t1.SHP_CUSTOM_5 = t2.SHP_CUSTOM_5 + 1
ORDER BY t1.SHP_CUSTOM_5
)
WHERE SHP_CUSTOM_5 = t.SHP_CUSTOM_5
);
但我仍然得到“操作必须使用可更新的查询。”
更新3:
我认为错误是由于我正在使用联合查询。为了隔离这个问题,我尝试了以下内容(这不会给我我想要的结果,但会帮助我诊断问题。):
UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
SELECT TOP 1 RECORD_TYPE
FROM tempSpring_ASN_With_PreviousRow
);
它给了我同样的错误。所以问题现在变成了,为什么我不能使用联合查询的输出的单个值来设置记录集中的值?
答案 0 :(得分:1)
我也在你的新问题中发布了这个答案。
嗨AYS,
在Access中,需要在表上运行Update查询。 由于UNION查询是多组记录的组合,因此结果集不再是表,并且不能成为Update查询的对象,因为结果集中的记录不再与任何一个特定表唯一标识(甚至如果他们理论上可能是)。 Access是硬编码的,可以将每个UNION查询视为只读,这在有多个基础表时是有意义的。还有许多其他条件(例如SELECT语句中的子查询)也会触发此条件。
以这种方式思考:如果你没有使用TOP 1并且你的UNION查询返回了多个结果,那么JET如何知道将哪个结果应用于表中的唯一记录?因此,JET将所有此类案件视为相同。
不幸的是,即使所有数据都来自同一个表,也是如此。在这种情况下,JET优化器可能根本不够智能,无法实现这种情况,并以不使用UNION的方式重新查询查询。
在这种情况下,您仍然可以通过重新查询查询来获得所需内容,以便所有内容都引用您的基表。例如,您可以使用以下作为SELECT查询来获取先前SHP_CUSTOM_5记录的PO_NUM值:
SELECT
t1.SHP_CUSTOM_5
, t1.PO_NUM
, t1.SHP_CUSTOM_5 -1 AS PREV_RECORD
, (SELECT
t2.PO_NUM
FROM
tempSpring_ASN As t2
WHERE
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1)
) AS PREV_PO
FROM
tempSpring_ASN AS t1
;
然后,您可以将此短语作为更新查询,如下所示,以执行“LIN”更新:
UPDATE
tempSpring_ASN AS t1
SET
t1.RECORD_TYPE = "LIN"
WHERE
t1.PO_NUM=
(
SELECT
t2.PO_NUM
FROM
tempSpring_ASN As t2
WHERE
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1)
)
;
此代码在我使用虚拟数据运行的测试中取得了成功。
关于“HDR”更新,您实际上正在执行两项单独的更新。 1)如果PO_NUM与先前记录的PO_NUM匹配,则将RECORD_TYPE设置为“LIN” 2)如果是第一条记录,请将RECORD_TYPE设置为“HDR”
我不清楚为什么在一个查询中执行这些操作会有好处。我建议使用您在原始SELECT查询示例中使用的SHP_CUSTOM_5方法使用“TOP 1”执行HDR更新,因为这将是一个相对简单的UPDATE查询。可以在更新查询中使用IIF(),但我不知道您将从所需的额外时间和复杂性中获得哪些额外好处(它很可能只是更不易读)。
祝你好运!