2017-03-14 8 views
0

가정하자 나는 다음과 같은 테이블 구조가 있습니다오라클 다중 행 문자 테이블과 조인 선택에서 '하지 않을 경우 삽입이 존재합니다'

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 백그라운드에서이 작업을하는 것이 쉽지는 않지만, 구체화 된 뷰를 작성한 후 순차적으로 삭제하거나 행당 하나의 삽입을 수행하지 않고 오라클에서이 작업을 수행하는 방법을 찾는 데 어려움을 겪고 있습니다.

내가 가지고 올 수 있었던 가장 추한 솔루션이었다

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_id, b_value) '를 입력으로합니까? 그것은 모든 질문에 답할 것입니다. 그대로, 당신은 잘못된 문제에 대한 올바른 해결책을 제시했습니다. – mathguy

+0

'a_id'와'a_code' 사이에 1 대 1의 관계가 있음을 잊어 버렸습니다. (그 질문을 반영하도록 수정합니다). 'a_code' 또한 고유하고 null이 아니라 단지 기본 키가 아닙니다. 내 리터럴은'new ','a_code, b_value'쌍으로 앨리어스 (alias)되어있다. 나는 각각의'a_code' 리터럴에 상응하는'a_id '를 얻기 위해 테이블'a'와 합류하기 때문에 삽입하고자하는'(a_id, b_value)'쌍을 얻고,'insert_codes'로 앨리어싱을합니다. 그래서 합병의'on' 절은 내가 이해할 수없고'insert_codes'에도 존재하지 않는 필드를 참조했기 때문에 실패했습니다. –