我在尝试在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值的记录。
您正在进行相关的更新,但是随后您再次引用了目标表。您尝试更新的每一行都将尝试将其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