2017-03-14 7 views
0

は、私は次の表の構造を持っているとしますOracleの複数行選択から「存在しない場合は挿入」リテラル

a (a_id number primary key, a_code varchar unique not null) 
b (b_id number primary key, a_id number foreign key references a(a_id), b_value varchar 

私は、彼らがしなければカップルにテーブルb(a_id, b_value)の百ペアを挿入する必要がありますまだ存在しておらず、私が持っている情報は(a_code, b_value)です。 Postgresのバックグラウンドから来ていますが、これは簡単ですが、マテリアライズドビューを作成してからドロップするか、1行に1つの挿入を行うことなく、Oracleでプルする方法を見つけるのが難しいです。

insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(b_value, iun_b_value) */ 
into b (b_id, a_id, b_value) 
select b_id.nextval, a_id, b_value 
from a 
inner join 

(select 'code1' a_code, 'value1' b_value from dual union all 
select 'code2' a_code, 'value2' b_value from dual union all 
select 'code3' a_code, 'value3' b_value from dual union all 
select 'code4' a_code, 'value4' b_value from dual) new 

on a.a_code = new.b_value 

しかし、私は、私は、生産上の重複行を処理するためにその意味的なヒントを使用することはできませんと言われたので、私はこの試みた:

これは私が思い付くことができた最も醜いソリューションでした

merge into b using 
    (select a_id, b_value 
    from a inner join 

    (select 'code1' a_code, 'value1' b_value from dual union all 
    select 'code2' a_code, 'value2' b_value from dual union all 
    select 'code3' a_code, 'value3' b_value from dual union all 
    select 'code4' a_code, 'value4' b_value from dual) new 

    new on a.a_code = new.a_code) insert_codes 

on (insert_codes.a_code = b.a_code and insert_codes.b_value = b.b_value) 
when not matched then 
    insert (b.b_id, b.a_id, b.b_value) 
    values (b_id.nextval, insert_codes.a_id, 1, insert_codes.b_value) 

しかし、私はwhere not exists句を使用してこの問題を解決しようとしているときに、私は副選択で別名を参照されたときに私はなっていた同じ"ORA-00980: synonym translation is no longer valid"エラーを取得します。

マテリアライズドビューまたは複数の挿入がなければ、それを行う方法はありますか?

答えて

0

私の単純化された例を見ると、私は何が間違っていたかを認識させました。 on句は

on (insert_codes.a_code = b.a_code and insert_codes.b_value = b.b_value) 

だったが、それは

on (insert_codes.a_id = b.a_id and insert_codes.b_value = b.b_value) 

だから、この作品のようになります。

他の誰かがトラブルにインサートの同じ種類をオフに引っ張っていた場合にここに投稿
merge into b using 
    (select a_id, b_value 
    from a inner join 

    (select 'code1' a_code, 'value1' b_value from dual union all 
    select 'code2' a_code, 'value2' b_value from dual union all 
    select 'code3' a_code, 'value3' b_value from dual union all 
    select 'code4' a_code, 'value4' b_value from dual) new 

    new on a.a_code = new.a_code) insert_codes 

on (insert_codes.a_id = b.a_id and insert_codes.b_value = b.b_value) 
when not matched then 
    insert (b.b_id, b.a_id, b.b_value) 
    values (b_id.nextval, insert_codes.a_id, 1, insert_codes.b_value) 

未来。

+0

質問には意味がありません。解決策は理にかなっていますが、あなたの質問と矛盾しています。あなたが持っている情報は '(a_code、b_value)'です。これは、あなたがどのa_idを添付するべきかを教えてくれないので意味をなさない。しかし、この解決法では、 "訂正された" 'on'節で' insert_codes.a_id'を使用します。だから、あなたは実際に入力として '(a_id、b_value)'ではなく '(a_code、b_value) 'を持っていますか?それはすべての質問に答えるだろう。それは間違った問題に対する正しい解決策でした。 – mathguy

+0

'a_id'と' a_code'の間に1対1の関係があることを忘れてしまいました。私の悪いことです(それを反映するために質問を編集します)。 'a_code'も一意のキーではなくヌルではなくユニークです。私のリテラルは 'new'とエイリアスされ、_are_'(a_code、b_value)'のペアです。 'a_code'リテラルごとに対応する' a_id'を取得するためにテーブル 'a'と結合するので、挿入する'(a_id、b_value) 'ペアを取得し、' insert_codes'としてエイリアスを追加します。ですから、マージの 'on'節は失敗していました。なぜなら、私が意味を持たず、' insert_codes'にも存在しないフィールドを参照していたからです。 –

関連する問題