在跨多个表连接时更新表

时间:2015-11-16 05:18:35

标签: sql oracle join sql-update

我(相当新)使用PL / SQL和Oracle 12c,并且我正在尝试实现的过程遇到问题。我在这里查了很多教程和类似的问题,但到目前为止,我没有找到任何可以帮助我的东西。情况是这样的:

我有三个表:table1,table2和table3。

  

Table1具有detailA和detailB属性。

     

Table2具有detailB和detailC属性。

     

Table3具有detailC和detailD属性。

我的目标是将table1中detailA的值更新为等于table2中的detailD。我知道为了做到这一点,我需要在detailB上连接table1和table2,然后在detailC上连接table2和table3。然而,实际上实现这一点却给我带来了麻烦。

到目前为止,我尝试过的所有内容都已经过了一半 - 我很难实现我需要检查的所有条件,同时仍然将其保留在PL / SQL的结构中。

这是我尝试过的一个(显然是非常错误的)例子:

    UPDATE (SELECT table1.detailB, table2.detailB, table2.detailC, 
    table3.detailC, table3.detail4 FROM table1
    JOIN table2 on table1.detailB =  table2.detailB
    JOIN table3 on table2.detailC = table3.detailD)
    SETtable1.detailA = table3.detail4;

如果有人能帮助我更好地理解这一点,我将非常感激。

编辑:对于一些实际数据的示例,如果我插入以下内容,它应该在我运行查询时将table1中的100替换为table4中的1000:

INSERT INTO table1(detailA, detailB) VALUES (100, 200);
INSERT INTO table2(detailB, detailC) VALUES (200, 400);
INSERT INTO table3(detailC, detailD) VALUES(400, 1000);

4 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题(示例数据会有很大帮助),那么我会使用MERGE语句,如下所示(经过测试):

MERGE INTO table1 -- The table you want to update 
USING 
(
  SELECT t2.detailB detailb, t2.detailC, t3.detailD detailD
  FROM table2 t2 inner join table3 t3
  ON (t2.detailC = t3.detailC)
) ta ON (ta.detailB = table1.detailB)
WHEN MATCHED THEN UPDATE 
    SET table1.detailA = ta.detailD;

FIDDLE

中测试过

答案 1 :(得分:0)

当您将列更新为在此选择查询中列出时

UPDATE (SELECT table1.detailB, 
                table2.detailB, 
                table2.detailC, 
                table3.detailC, 
                table3.detail4,
                table1.detailA 
         FROM table1
    JOIN table2 on table1.detailB =  table2.detailB
    JOIN table3 on table2.detailC = table3.detailD)
    SET detailA = detail4;

答案 2 :(得分:0)

试试这个:

UPDATE (SELECT  t1.detailA,
                t1.detailB, 
                t2.detailB, 
                t2.detailC, 
                t3.detailC, 
                t3.detailD                    
        FROM table1 t1 JOIN table2 t2 ON t1.detailB =  t2.detailB
                       JOIN table3 t3 ON t2.detailC =  t3.detailC)

SET t1.detailA = t3.detailD;

答案 3 :(得分:0)

您应该回答的第一个问题是,如果更新不是确定性的该怎么办。请考虑以下数据

INSERT INTO table1(detailA, detailB) VALUES (100, 200);
INSERT INTO table2(detailB, detailC) VALUES (200, 400);
INSERT INTO table3(detailC, detailD) VALUES(400, 1000); -- which value should I update?? 1000
INSERT INTO table3(detailC, detailD) VALUES(400, 1001); -- or 1001

典型的答案是将其视为无效数据并设置禁用它们的约束。 请注意,Oracle使用 ORA-01779错误保护此错误:无法修改映射到非密钥保留表的列

您可以按如下方式定义主键以使更新安全:

alter table table2 add (primary key (detailB));
alter table table3 add (primary key (detailC));

之后,您可以执行更新联接(内联)视图

UPDATE (
SELECT table1.detailA, table3.detailD 
FROM table1
    JOIN table2 on table1.detailB =  table2.detailB
    JOIN table3 on table2.detailC = table3.detailC
)
set detailA = detailD
;

SELECT table1.detailA 
FROM table1
;

1000