无法更新数据库中的列

时间:2014-07-22 05:11:58

标签: sql oracle

我必须使用另一列中的值更新一个表中的列,这是另一个表。我必须更新大约100000条记录(不是单行更新)。

我的查询是

update asset_dmr_revision adr 
   set adr.revision_date = (select adrt.revision_date_test 
                              from asset_dmr_revision_test adrt,
                                   asset_dmr_revision ad 
                             where ad.id = adrt.id 
                               and adrt.revision_date_test is not null
                               and ad.asset_id = adrt.asset_id) 

但是当我在toad中运行时,它说“单行子查询返回多行”。如何更新所有coumns?我正在使用oracle

5 个答案:

答案 0 :(得分:1)

内部选择:

select adrt.revision_date_test 
from asset_dmr_revision_test adrt, asset_dmr_revision ad 
where ad.id = adrt.id 
and adrt.revision_date_test is not null
and ad.asset_id = adrt.asset_id

返回多行 - 因此数据库变得“混乱”,并且不知道选择哪一行......

答案 1 :(得分:1)

就像我在评论中说的那样,你只需要返回一行。 您可以使用以下函数来实现此目的:

update asset_dmr_revision adr 
   set adr.revision_date = (select max(adrt.revision_date_test) 
                              from asset_dmr_revision_test adrt,
                                   asset_dmr_revision ad 
                             where ad.id = adr.id 
                               and adrt.revision_date_test is not null
                               and ad.asset_id = adrt.asset_id
                               group by ad.id)

在您的情况下用功能正确的功能替换MAX。

此外,如果值为NULL,则可能需要指定默认值:

update asset_dmr_revision adr 
   set adr.revision_date = nvl((select max(adrt.revision_date_test) 
                              from asset_dmr_revision_test adrt,
                                   asset_dmr_revision ad 
                             where ad.id = adr.id 
                               and adrt.revision_date_test is not null
                               and ad.asset_id = adrt.asset_id
                               group by ad.id),adr.revision_date_test)

答案 2 :(得分:1)

您似乎想要更新与子查询匹配的每一行。为此,我建议使用merge

MERGE INTO asset_dmr_revision adr
USING      (SELECT adrt.id, adrt.revision_date_test
            FROM   asset_dmr_revision_test adrt
                   JOIN asset_dmr_revision ad
                      ON ad.id = adrt.id AND adrt.asset_id = ad.asset_id
            WHERE  adrt.revision_date_test IS NOT NULL) a
ON         (adr.id = s.id)
WHEN MATCHED THEN
   UPDATE SET revision_date = s.revision_date

答案 3 :(得分:0)

and rownum = 1and rownum <=1添加到内部选择查询中。这将确保内部查询始终只返回1条记录。

select adrt.revision_date_test 
                             from asset_dmr_revision_test adrt,
                                   asset_dmr_revision ad 
                             where ad.id = adrt.id 
                               and adrt.revision_date_test is not null
                               and ad.asset_id = adrt.asset_id
                               and rownum <= 1

注意:在我看来,rownum <=1rownum=1提供更好的效果

编辑:

尝试以下更新查询:

update asset_dmr_revision adr 
   set adr.revision_date = nvl(select adrt.revision_date_test 
                              from asset_dmr_revision_test adrt,
                              asset_dmr_revision ad 
                               where ad.id = adrt.id 
                               and adrt.revision_date_test is not null
                               and ad.asset_id = adrt.asset_id
                   and adr.id = adrt.id
                   and rownum <=1
                   ) , adr.revision_date);

基本上,外部adr表和内部adrt表之间没有相关性。所以我添加了附加条件and adr.id = adrt.id。检查并告诉我它是否有帮助。

答案 4 :(得分:0)

我写了一个解决问题的程序。非常感谢Alfsin和Nishanthi的支持.. :)

CREATE OR REPLACE procedure DTV_B2B2.update_revision_date is 

cursor revDate  is (select revision_date_test,id from asset_dmr_revision_test);

begin
--DBMS_OUTPUT.put_line ('outside loop');
for rec in revDate 
loop
update asset_dmr_revision adr set adr.revision_date = rec.revision_date_test
where adr.id = rec.id;
end loop;
end;