테이블명 : yeardata
pk : year, seq
초기 테이블 데이터 없는 상태임.
case 1.
변수값
year | seq | data |
2020 | 1 | 200 |
2021 | 2 | 300 |
2022 | 3 | 400 |
처리 결과
year | seq | status | data |
2020 | 1 | C | 200 |
2021 | 2 | C | 300 |
2022 | 3 | C | 400 |
설명
1. DB에 없는 변수값을 Insert(status : C)
case 2.(case 1 결과값이 DB 데이터)
변수값
year | seq | data |
2020 | 1 | 200 |
2021 | 2 | 250 |
처리 결과
year | seq | status | data |
2020 | 1 | U | 200 |
2021 | 2 | U | 250 |
2022 | 3 | D | 400 |
설명 :
1. 2020, 2021 -> 변수값과 DB 데이터간 pk(year, seq) 조건 데이터가 있는 경우 status, data 값 update(C -> U)
2. 2022 -> DB 데이터에는 있으나 변수값에 없는 경우 status 값 update(C -> D)
case 3.(case 2 결과값이 DB 데이터)
변수값
year | seq | data |
2020 | 1 | 100 |
2021 | 2 | 250 |
2022 | 4 | 500 |
2023 | 5 | 550 |
처리 결과
year | seq | status | data |
2020 | 1 | U | 100 |
2021 | 2 | U | 250 |
2022 | 3 | D | 400 |
2022 | 4 | C | 500 |
2023 | 5 | C | 550 |
설명
1. seq 1, 2, 3은 case 2와 같은 경우
2. seq 4, 5 번은 DB에 없는 신규 데이터라 Insert(case 1과 같은 경우)
하나의 merge 문으로 위 경우를 모두 처리할 수 있는지 문의 드립니다.
-- 변수값을 임시테이블에 입력 한 뒤에 다음과 같이 처리하세요. MERGE INTO yeardata a USING ( SELECT NVL(a.year, b.year) year , NVL(a.seq , b.seq ) seq , NVL(b.data, a.data) data , DECODE(null, a.seq, 'C', b.seq, 'D', 'U') status FROM yeardata a FULL OUTER JOIN input_t b ON a.year = b.year AND a.seq = b.seq ) b ON (a.year = b.year AND a.seq = b.seq) WHEN MATCHED THEN UPDATE SET status = b.status , data = b.data WHEN NOT MATCHED THEN INSERT VALUES (b.year, b.seq, b.status, b.data) ;
-- 글쎄요? 변수 자체로는 안될 것 같습니다. -- 어떻게 해서든 테이블 형태로 처리가 되어야 할텐데요. -- MERGE INTO yeardata a USING ( WITH input_t(year, seq, data) AS ( SELECT '2020', 1, 200 FROM dual UNION ALL SELECT '2021', 2, 300 FROM dual UNION ALL SELECT '2022', 3, 400 FROM dual ) SELECT NVL(a.year, b.year) year , NVL(a.seq , b.seq ) seq , NVL(b.data, a.data) data , DECODE(null, a.seq, 'C', b.seq, 'D', 'U') status FROM yeardata a FULL OUTER JOIN input_t b ON a.year = b.year AND a.seq = b.seq ) b ON (a.year = b.year AND a.seq = b.seq) WHEN MATCHED THEN UPDATE SET status = b.status , data = b.data WHEN NOT MATCHED THEN INSERT VALUES (b.year, b.seq, b.status, b.data) ;
-- 변수로 루프 돌려가면서 1건씩 처리한다고 하면 -- 처리 전 전체 데이터를 D 로 업데이트 한 후에 -- 루프 처리로 한건씩 머지하면 될 듯 합니다. -- 1. 전체 D 로 갱신 UPDATE yeardata SET status = 'D'; -- 2. LOOP 문 안에서 1건씩 Merge -- MERGE INTO yeardata a USING dual ON (a.year = :v_year AND a.seq = :v_seq) WHEN MATCHED THEN UPDATE SET status = 'U' , data = :v_data WHEN NOT MATCHED THEN INSERT VALUES (:v_year, :v_seq, 'C', :v_data) ;