Sql 跨多个表连接时更新表

Sql 跨多个表连接时更新表,sql,oracle,join,sql-update,Sql,Oracle,Join,Sql Update,我(对)在Oracle12c中使用PL/SQL是(相当陌生的),我在尝试实现一个过程时遇到了问题。我在这里查阅了很多教程和类似的问题,但到目前为止,我还没有找到任何可以帮助我的东西。情况是这样的: 我有三张桌子:表一、表二和表三 表1具有属性detailA和detailB 表2具有detailB和detailC属性 表3具有detailC和detailD属性 我的目标是更新表1中detailA的值,使之等于表2中的detailD。我知道为了做到这一点,我需要在detailB上连接表1和表2,然后

我(对)在Oracle12c中使用PL/SQL是(相当陌生的),我在尝试实现一个过程时遇到了问题。我在这里查阅了很多教程和类似的问题,但到目前为止,我还没有找到任何可以帮助我的东西。情况是这样的:

我有三张桌子:表一、表二和表三

表1具有属性detailA和detailB

表2具有detailB和detailC属性

表3具有detailC和detailD属性

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

到目前为止,我所尝试的一切都在中途偏离了轨道——我很难实现所有需要检查的条件,同时仍将其保持在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;
如果有人能帮我更好地理解这一点,我将非常感激

编辑:对于一个有一些实际数据的示例,如果我插入以下内容,当我运行查询时,它应该将表1中的100替换为表4中的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);

当您将列更新为在select查询中列出时,如下所示

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;

如果我正确地理解了您的问题(样本数据会很有帮助),那么我将使用以下语句(已测试):

中测试尝试以下方法:

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;

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

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));
之后,可以执行连接(内联)视图的更新


不幸的是,当我尝试这样做时,PLSQL在“FROM”上注册了一个错误,如果我尝试运行它,我会在命令行得到:error:9 Column:2 error report-SQL error:ORA-00933:SQL命令未正确结束00933。00000-“SQL命令未正确结束”*原因:*操作:@A.M.Roxford现在检查此查询我尝试了新查询!有一个轻微的输入错误——您在一些地方编写了table4,而不是detailD——但一旦我统一了这些内容,在尝试运行它时就会抛出以下错误:SQL错误:ORA-01779:无法修改映射到非键保留表01779的列。00000-“无法修改映射到非键保留表的列”*原因:试图插入或更新映射到非键保留表的联接视图的列*操作:直接修改基础基表。在最后一行中,我还尝试将table1.detailA替换为detailA,将table4.detailD替换为detailD,但这反而导致出现错误:SQL错误:ORA-00904:“table4”。“detailD”:无效标识符00904。00000-“%s:invalid identifier”(哦,很抱歉!我将立即添加一些)。我尝试运行此程序,但它似乎与“ta”有问题。它告诉我:SQL错误:ORA-00918:列定义模糊00918。00000-“列定义模糊”@A.M.Roxford已更正,并已成功测试。请参阅上面的链接哦,太棒了!非常感谢您的帮助。当我尝试运行此程序时,它告诉我:错误报告-SQL错误:ORA-00904:“T3”。“DETAILD”:无效标识符00904。00000-“%s:invalid identifier”查询最后一行的某些内容似乎触发了错误。您确定表3中详细说明了列名吗?我非常确定,是的。我的表create语句是CREATETABLETABLE3(detailC int,detailD int,primary key(detailC));如果这有帮助的话。关于“相当新”:有一件事你应该理解:PL/SQL和Oracle中的SQL之间有着明显的区别。PL/SQL用于存储过程、触发器和函数(或匿名PL/SQL块)。其他一切都是“普通”SQL。您的问题只是关于SQL,而不是PL/SQL@a_horse_with_no_name哦,对了,谢谢你!我搞混了,因为我在这个项目中使用了大量的PL/SQL——只是不适用于这个特殊的部分。
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