1

问题描述:需要从平面文件匹配和更新新的描述(如果不同)生产表。在 temptable 中导入了平面文件。

sample from prod table:
[mstr_plan]

char(5)    varchar2(30) char(3)
PLAN_CODE PLAN_DESC FIN_CLUSTER
BB123     Plan_desc3 Z01
BB124     Plan_desc4 Z02
BB125     Plan_desc5 Z02
BB126     Plan_desc6 Z03
BB127     Plan_desc7 Z04
BB128     Plan_desc8 Z06
<about 500 records>

tmptbl01 <new records from flat file)
PLAN_CODE PLAN_DESC    FIN_CLUSTER
BB123     Plan_desc3    Z01
BB124     Plan_desc4    Z02
BB125     Plan_desc51   Z02
BB126     Plan_desc61   Z03
BB127     Plan_desc7    Z04
BB128     Plan_desc81   Z06
<about 150 records>

选择查询:

select * from mstr_plan, tmptbl01
where mstr_plan.plan_code = tmptbl01.plan_code and 
(mstr_plan.PLAN_DESC <> tmptbl01.PLAN_DESC or
mstr_plan.FIN_CLUSTER <> tmptbl01.FIN_CLUSTER);

<in my database with 500 & 150 rows it returns 17 rows>
<in sample should return 3 rows>
PLAN_CODE PLAN_DESC    FIN_CLUSTER
BB125     Plan_desc51   Z02
BB126     Plan_desc61   Z03
BB128     Plan_desc81   Z06

FIN_CLUSTER 没有变化。因此,将其从更新查询中取出。

UPDATE mstr_plan 
SET mstr_plan.PLAN_DESC = 
(select tmptbl01.plan_desc from mstr_plan, tmptbl01 where mstr_plan.plan_code=
 tmptbl01.plan_plan_code and mstr_plan.plan_desc <> mstr_plan.plan_desc )

where mstr_plan.PLAN_DESC = <or IN>
(select tmptbl01.plan_desc from mstr_plan, tmptbl01 where mstr_plan.plan_code=
 tmptbl01.plan_plan_code and mstr_plan.plan_desc <> mstr_plan.plan_desc )

返回 ORA-01427: 单行子查询返回多于一行

方法: <1> 手动逐一更新 17 条记录 <2> 了解一个粗略的方法来“and where with rownum = 1”。还没试过。

请推荐我更好的方法。

4

1 回答 1

2

该错误是因为您已将mstr_plan表放在子查询中。

即使您更正了这一点,您的任何UPDATE陈述都不会起作用,因为它们包含and mstr_plan.plan_desc <> mstr_plan.plan_descWHERE子句中,使其始终为假。

通常最好使用SELECT您已有的变体并正确找到要更新的行。您只需要选择要更新的列和新值,然后更新此派生表:

UPDATE 
    ( SELECT mstr_plan.plan_desc 
           , tmptbl01.plan_desc AS new_plan_desc 
      FROM mstr_plan 
        JOIN tmptbl01 
          ON mstr_plan.plan_code = tmptbl01.plan_code 
      WHERE mstr_plan.plan_desc <> tmptbl01.plan_desc  
    ) 
SET plan_desc = new_plan_desc ;

这样,如果您在代码中出错,您更新错误行的机会就会减少(如果您WHERE始终为 true 而不是始终为 false,您可能已经更新了mstr_plan表中的所有行,可能会将一些NULL值放在 (500-17 ) 不应更新的行。

您还可以使用别名使其更具可读性:

UPDATE 
    ( SELECT m.plan_desc 
           , t.plan_desc AS new_plan_desc 
      FROM mstr_plan  m
        JOIN tmptbl01  t
          ON m.plan_code = t.plan_code 
      WHERE m.plan_desc <> t.plan_desc  
    ) 
SET plan_desc = new_plan_desc ;
于 2013-01-21T22:06:38.847 回答