【问题标题】:Is there a way to include a query that is non updateable in an UPDATE query? [duplicate]有没有办法在 UPDATE 查询中包含不可更新的查询? [复制]
【发布时间】:2013-01-30 21:02:39
【问题描述】:

对于以下查询:

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 提供的解决方案(下面也提供)不适用于这种情况,与本页顶部的说明相反。)

【问题讨论】:

  • @invertedSpear ,这不是 可能 重复的。我自己参考了它。我这样做是为了让人们更容易跟随。 :-)
  • 之所以这样标记,是因为堆栈溢出的目的不是成为一个带有指向先前问题的反向链接的论坛。如果您的问题不同,那是一回事,但如果您只是提供额外的详细信息或说明,就像您在这里所做的那样,您应该对原始问题进行编辑。关键是网络搜索应该出现一个问题,而不是需要跟随其他问题的链接才能弄清楚发生了什么的问题。 SO 不仅仅是帮助你,它还应该能够轻松帮助未来遇到类似问题的任何人。
  • @invertedSpear ,听起来你声称我将它分成 2 个线程以使我更容易,但以牺牲其他所有人使用 SO 为代价。讽刺的是,恰恰相反!对我来说,拥有一个线程会更容易,但我专门创建了一个新线程来其他人更容易。在我的特定情况下,这两个问题背后都有一个目标,但实际上,这两个问题可以相互独立地工作。 JAGAnalyst的回答其实只回答了其他帖子,没有回答这个。
  • @invertedSpear,因此,请您删除“重复”标签,因为这是不准确的,并且会使其他人更难使用该网站。谢谢!

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


【解决方案1】:

这个问题是对之前发布的问题、数据和代码示例的参考:

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

嗨,AYS,

在 Access 中,需要对表运行更新查询。 由于 UNION 查询是多组记录的组合,结果集不再是一个表,也不能成为 Update 查询的对象,因为结果集中的记录不再与任何一个特定表唯一标识(甚至如果理论上可以的话)。访问被硬编码以将每个 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 查询。可以在 Update 查询中使用 IIF(),但我不知道您会从所需的额外时间和复杂性中获得什么额外好处(它很可能只是可读性低得多)。

祝你好运!

【讨论】:

  • 您的查询没有任何“错误”。 Access 只是说你不能,所以你不能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2011-03-04
  • 1970-01-01
  • 2011-04-13
  • 2011-10-03
  • 1970-01-01
相关资源
最近更新 更多