带有左连接的 Oracle 更新

Posted

技术标签:

【中文标题】带有左连接的 Oracle 更新【英文标题】:Oracle update with a left join 【发布时间】:2020-03-06 16:43:23 【问题描述】:

我想简单地使用传入的参数更新单个表的行集,而不是从另一个表中,而是为了识别行,我需要进行左连接。这是要选择的查询:

SELECT *
FROM SAMPLE_STATUS pss
  LEFT JOIN QC q ON q.SAMPLE_ID = pss.SAMPLE_ID
WHERE q.CONTRACT_CLN_ID = 28 AND q.LOT = 1

我已经尝试了几个例子,这是最后一个只有一列的例子

UPDATE 
  (SELECT pss.APP_WIN_START_DT, TO_CHAR(sysdate, 'YYYYMMDD') AS NEW_AWSD
  FROM SAMPLE_STATUS pss
    LEFT JOIN QC q ON q.SAMPLE_ID = pss.SAMPLE_ID
  WHERE q.CONTRACT_CLN_ID = 28 AND q.LOT = 1) pq
  SET APP_WIN_START_DT = NEW_AWSD

从 QC 表中提取了几条记录,这些记录通过样本 id 连接到 Sample_Status 表。我得到的错误是:

SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 -  "cannot modify a column which maps to a non key-preserved table"
*Cause:    An attempt was made to insert or update columns of a join view which
           map to a non-key-preserved table.
*Action:   Modify the underlying base tables directly.

提前致谢。

【问题讨论】:

我想SAMPLE_ID 列在两个表中都没有唯一键或主键。 【参考方案1】:

我认为您实际上需要内部连接逻辑,但无论如何您都可以使用 exists 编写此更新:

UPDATE SAMPLE_STATUS pss
SET APP_WIN_START_DT = TO_CHAR(sysdate, 'YYYYMMDD')
WHERE EXISTS (SELECT 1 FROM QC q
              WHERE q.SAMPLE_ID = pss.SAMPLE_ID AND
                    q.CONTRACT_CLN_ID = 28 AND q.LOT = 1);

我怀疑您在这里不想要左连接的原因是您正在更新连接左侧的表字段。但是由于右侧表的 where 子句有限制,它的行为就像一个内连接。

【讨论】:

以上是关于带有左连接的 Oracle 更新的主要内容,如果未能解决你的问题,请参考以下文章

包含左连接的 SQL Oracle 更新

当我们在 select 中有 case 语句时,使用左外连接进行 Oracle 更新

选择带有“is null”子句的查询和子选择/左连接不返回结果

oracle 中在左连接的时候不能全部显示左表中的数据

oracle中的右连接和左连接有啥区别?如果我们可以实现左连接在右连接中可以做的事情,为啥要使用 2 个单独的连接?

oracle左连接与右连接