有没有办法在UPDATE查询中包含一个不可更新的查询?

时间:2013-02-14 22:36:41

标签: sql ms-access sql-update subquery union-all

对于以下查询:

UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
        SELECT TOP 1 RECORD_TYPE
        FROM (
            SELECT "A" AS RECORD_TYPE
            FROM TABLE5
            UNION ALL
            SELECT "B" AS RECORD_TYPE
            FROM TABLE5
            )
        );

我收到了,“操作必须使用可更新的查询。”我不明白。我不是要尝试更新联合查询。我只是尝试使用联合查询的输出(单值)更新其他可更新的记录集。

Access SQL Update One Table In Join Based on Value in Same Table提供的解决方案(下面也提供)对于这种情况不起作用,与本页顶部的内容相反。)

1 个答案:

答案 0 :(得分:2)

此问题是对此前发布的上一个问题,数据和代码示例的引用:

Access SQL Update One Table In Join Based on Value in Same Table

嗨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(),但我不知道您将从所需的额外时间和复杂性中获得哪些额外好处(它很可能只是更不易读)。

祝你好运!