Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何将数据从表A中的一列复制到Oracle中的表B_Sql_Oracle - Fatal编程技术网

Sql 如何将数据从表A中的一列复制到Oracle中的表B

Sql 如何将数据从表A中的一列复制到Oracle中的表B,sql,oracle,Sql,Oracle,我有两个表,表A和表B。表A有一个项目名称列表及其唯一ID。表B列出了这些相同的项目名称,但没有ID。我想根据项目名称将ID复制到表B。我已经在表B中的一个单独命令中创建了该列,但是我很难弄清楚如何复制它。我使用了以下代码: Update B Set B.ID = (Select A.ID From A Where A.Name = B.Name) Where Exists (Select A.ID From A Where A.Name = B.Name); 但我一直在犯错误。明确地: S

我有两个表,表A和表B。表A有一个项目名称列表及其唯一ID。表B列出了这些相同的项目名称,但没有ID。我想根据项目名称将ID复制到表B。我已经在表B中的一个单独命令中创建了该列,但是我很难弄清楚如何复制它。我使用了以下代码:

Update B
Set B.ID = 
(Select A.ID From A Where A.Name = B.Name)
Where Exists (Select A.ID From A Where A.Name = B.Name);
但我一直在犯错误。明确地: SQL错误:ORA-01427:单行子查询返回多行 142700000-单行子查询返回多行

ID是字母数字的。名称和ID不一定是唯一的,因此如果名称值递归,我希望它仍然分配正确的ID


帮助?

您必须定义正确的id。您可以使用rownum或聚合函数轻松获取一个id:

Update B
    Set B.ID = (Select A.ID From A Where A.Name = B.Name and rownum = 1)
    Where Exists (Select A.ID From A Where A.Name = B.Name);
或:

其中一个可以解决您的问题

虽然我不推荐,但您也可以获得所有匹配ID的列表:

Update B
    Set B.ID = (Select listagg(A.ID, ',') within group (order by A.ID) From A Where A.Name = B.Name)
    Where Exists (Select A.ID From A Where A.Name = B.Name);

不过,我不喜欢将列表存储为逗号分隔的字符串。

另一种方法是使用for循环,请参见下面的代码

BEGIN
    FOR tab_a IN (SELECT ID, NAME
                    FROM table_a)
    LOOP
         UPDATE table_b
            SET id = tab_a.id
          WHERE name = tab_a.name;
         --comment dbms_output if a lot of records involved or you can increase the output size
         DBMS_OUTPUT.PUT_LINE(tab_a.name||':::'||SQL%ROWCOUNT);
    END LOOP;
END;
/

COMMIT;

更新B Set B.ID=从A中选择maxA.ID,其中A.Name=B.Name在A中至少有两行具有相同的名称。那么,在这个场景中,您希望在表B中存储什么?两个身份证?其中一个,如果是,哪一个?ID是字母数字的。是的,我想把ID复制到这两个地方。名称和ID不一定是唯一的,因此,如果名称值递归,我希望它仍然分配正确的ID。如果名称值递归时可能使用不同的ID,那么要复制到另一个表的正确ID是什么?我讨厌存储列表。。。你们是一个很好的伙伴,第一个普通表单也是如此。这可能比SQL选项慢得多。此外,它以一种神秘的方式解决了太多行的问题,因为您不知道将为哪个名称分配哪个ID。当然是最后一个,但是——是哪一个?游标循环的SELECT语句中没有ORDERBY子句。我觉得我不太喜欢这样的解决方案。按顺序排序是个好主意,但我认为没有必要,因为表a包含唯一的记录名称和ID,如果我的假设是正确的,并且表b中的一个或多个记录可以包含类似的名称,上面的UPDATE语句可能会更新一个或多个记录,这就是为什么我在下面的行中输入更新的记录数,如果在应用程序中使用下面的UPDATE,我同意您的说法,这可能是较慢的选择,但我认为不会始终使用此问题的解决方案,也许只有一次这样性能就不会是一个问题。所以,我不明白你为什么提到太多行,因为上面的代码中没有SELECT INTO子句,这只是一个更新。我认为你的假设是错误的-有重复的名称,这就是为什么OP的查询返回太多行OP的,而不是你的。此外,这就是为什么您的解决方案为所有这些重复项的名称设置相同的ID(游标FOR循环中最后选择的ID),这是不应该发生的。啊,好吧,如果是这样,那么您可能是对的,谢谢
BEGIN
    FOR tab_a IN (SELECT ID, NAME
                    FROM table_a)
    LOOP
         UPDATE table_b
            SET id = tab_a.id
          WHERE name = tab_a.name;
         --comment dbms_output if a lot of records involved or you can increase the output size
         DBMS_OUTPUT.PUT_LINE(tab_a.name||':::'||SQL%ROWCOUNT);
    END LOOP;
END;
/

COMMIT;