尝试通过SQL加载程序更新表时出错

问题描述 投票:0回答:1

我在尝试在Oracle表上进行更新时遇到问题,但不断出现错误,无法看到其他任何方式来编写所需的脚本。

01427. 00000 -  "single-row subquery returns more than one row"

我需要将我的REFERENCES表中的所有ID_VALUE更新为我的临时表中的COM值。只要它们连接到在临时表中具有匹配的ITN作为其ID_VALUE的ITN行。

临时表的值存储在txt文件中,我有一个ctl文件将这些值加载到临时表中,并调用下面的sql进行更新。

STAGE_TABLE :(临时表)

ITN             COM
NO000445        765775518
N04009          208784526

参考表:

REFERENCE_ID    JOB_ID ID_TYPE  ID_VALUE
1               1065    VAL     00601       
2               1065    ITN     NO000445    
3               1065    COM     00018903    
4               1065    SEC     SA897215        
5               1066    COM     0005675 
6               1066    ITN     N04009  
7               1066    SEC     SA1402877       
8               1066    VAL     006292  

我用来尝试更新的SQL。

BEGIN
     UPDATE REFERENCES F
     SET F.ID_VALUE = (
            SELECT STG.COM
            FROM STAGE_TABLE STG, REFERENCES F
            WHERE STG.ITN = F.ID_VALUE
        )
     WHERE F.REFERENCE_ID IN
      (
        SELECT F1.REFERENCE_ID
        FROM STAGE_TABLE STG, REFERENCES F1, REFERENCES F2
        WHERE F1.ID_TYPE = 'COM'
        AND F2.ID_TYPE = 'ITN'
        AND F2.ID_VALUE = STG.ITN
        AND F2.JOB_ID = F1.JOB_ID
    );

    COMMIT;

EXCEPTION
     WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE ('Error');
        ROLLBACK;
        RAISE;
END;
/

任何帮助将不胜感激。这让我发疯。

REFERENCES表中的预期结果:

REFERENCE_ID    JOB_ID ID_TYPE  ID_VALUE
1               1065    VAL     00601       
2               1065    ITN     NO000445    
3               1065    COM     765775518    
4               1065    SEC     SA897215        
5               1066    COM     208784526 
6               1066    ITN     N04009  
7               1066    SEC     SA1402877       
8               1066    VAL     006292 

所以只有COM的ID_VALUE已更改为临时表中的值,因为存在ITN值的记录。

oracle sql-update sql-loader
1个回答
0
投票

您正在进行相关的更新,但是随后您再次引用了目标表。您尝试更新的每一行都将尝试将其id_value设置为子查询的结果:

SELECT STG.CODE
FROM STAGE_TABLE STG, REFERENCES F
WHERE STG.ITN = F.ID_VALUE

这将是许多值,而不是所需的单个值-因此会出现错误。该子查询中的references完全独立于外部update语句中的references。 (顺便说一句,“引用”是一个keyword,因此可能是一个令人困惑的对象名称。)

在子查询中取出新的references

UPDATE REFERENCES F
SET F.ID_VALUE = (
    SELECT STG.COM
    FROM STAGE_TABLE STG
    WHERE STG.ITN = F.ID_VALUE
)
WHERE F.REFERENCE_ID IN
(
    SELECT F1.REFERENCE_ID
    FROM STAGE_TABLE STG
    JOIN REFERENCES F2 ON F2.ID_VALUE = STG.ITN
    JOIN REFERENCES F1 ON F1.JOB_ID = F2.JOB_ID
    WHERE F1.ID_TYPE = 'COM'
    AND F2.ID_TYPE = 'ITN'
);

您的IN子查询看起来也有些奇怪。首先,您应该使用ANSI连接语法;但是还不清楚它们之间的关系。我认为我所做的只是笔直的翻译,但不是100%的是您真正想要的。

您在这里也不需要使用任何PL / SQL,您可以将其作为普通的SQL语句运行。


使用示例数据,过滤器子查询将找到reference_id结果3和5。然后更新这些ID的匹配参考。对应于那些行的id_values是00018903和0005675,并且stage_table中没有匹配的行。

您将在该子查询中获取'COM'参考ID,而不是ITN;所以你想要:

UPDATE REFERENCES F
SET F.ID_VALUE = (
    SELECT STG.COM
    FROM STAGE_TABLE STG
    WHERE STG.ITN = F.ID_VALUE
)
WHERE F.REFERENCE_ID IN
(
    SELECT F2.REFERENCE_ID
    FROM STAGE_TABLE STG
    JOIN REFERENCES F2 ON F2.ID_VALUE = STG.ITN
    JOIN REFERENCES F1 ON F1.JOB_ID = F2.JOB_ID
    WHERE F1.ID_TYPE = 'COM'
    AND F2.ID_TYPE = 'ITN'
);

select * from references;

REFERENCE_ID     JOB_ID ID_ ID_VALUE 
------------ ---------- --- ---------
           1       1065 VAL 00601    
           2       1065 ITN 765775518
           3       1065 COM 00018903 
           4       1065 SEC SA897215 
           5       1066 COM 0005675  
           6       1066 ITN 208784526
           7       1066 SEC SA1402877
           8       1066 VAL 006292   

db<>fiddle

© www.soinside.com 2019 - 2024. All rights reserved.