1

問題desc:フラットファイルから新しいdesc(異なる場合)本番テーブルを照合して更新する必要があります。フラットファイルを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個のレコードを1つずつ手動で更新します<2>大まかなメソッドについて'およびrownum=1'に読み取ります。まだ試していません。

より良い方法をお勧めしてください。

4

1 に答える 1

2

エラーはmstr_plan、サブクエリ内にテーブルを配置したためです。

ただし、それを修正したとしても、句に含まれてUPDATEいるため、どのステートメントも機能せず、常にfalseになります。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常にfalseではなく常にtrueの場合は、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 に答える