h3.1. MERGE 구문으로 처리되는 데이터 이해하기
테스트환경
[MERGE_T1 TERGET 테이블 생성]
create table merge_t1
as
select level as c1, chr(65+mod(level,26)) as c2, level+99999 as c3
from DUAL
connect by level <= 100000 ;
[MERGE_T1 인덱스 생성]
create index merge_t1_idx_01 on merge_t1 ( c1 ) ;
[MERGE_T1 통계정보 수집]
exec dbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'merge_t1',cascade=>TRUE,estimate_percent=>100) ;
[MERGE_T2 SOURCE 테이블 생성]
create table merge_t2
as
select level as c1, chr(65+mod(level,26)) as c2,
decode(mod(level,10),0,null,mod(level,10)) as c3
from DUAL
connect by level <= 500000 ;
[MERGE_T2 인덱스 생성]
create index merge_t2_idx_01 on merge_t2 ( c1 ) ;
[MERGE_T2 통계정보 수집]
exec dbms_stats.gather_table_stats(ownname=>'SCOTT',tabname=>'merge_t2',cascade=>TRUE,estimate_percent=>100) ;
테스트 구문
MERGE INTO merge_t1 tt
USING (
SELECT c1, c2, c3
FROM MERGE_T2
WHERE c1 >= 99990
AND c1 <= 100090
) st
ON (tt.c1 = st.c1)
WHEN MATCHED THEN
UPDATE SET tt.c2 = st.c2, ttC3 = st.c3
DELETE WHERE (tt.c2 = 'A' )
WHERE NOT MATCHED THEN
INSERT (tt.C1, tt.c2, tt.c3) VALUES (st.c1, st.c2, st.c3)
WHERE (st.c2 = 'A');
UPDATE 대상확인
USING 절에서 추출한 소스테이블의 데이터 중 타겟 테이블에 존재하는 데이터(st.c1 = tt.c1) 가 UPDATE 대상이 됨을 확인할 수 있다
SELECT COUNT(*)
FROM (SELECT c1, c2, c3
FROM MERGE_T2
WHERE c1 >= 99990
AND c1 <= 100090
)st, MERGE_T1 tt
WHERE st.c1 = tt.c1;
COUNT(*)
--------
11 <-- 총 11건이 UPDATE 대상임
WHEN MATCHED THEN 데이터
C1 | C2 | C3 |
---|---|---|
99990 | U | |
99991 | V | 1 |
99992 | W | 2 |
99993 | X | 3 |
99994 | Y | 4 |
99995 | Z | 5 |
99996 | A | 6 |
99997 | B | 7 |
99998 | C | 8 |
99999 | D | 9 |
100000 | E | |
총 11건의 MATCHED 데이터중 10건이 UPDATE 되고 1건이 DELETE 됨.
DELETE 대상확인
USING 절에서 추출한 소스테이블의 데이터 중 타겟 테이블에 존재하고(st.c1 = tt.c1) (st.c2= 'A')조건에 만족하는 타켓 테이블의 데이터가 DELETE 대상임.
SELECT COUNT(*)
FROM MERGE_T1
WHERE c1 >= 99990
AND c1 <= 100000
AND c2 = 'A'; ---> MERGE 구문의 DELETE 시 체크 조건
COUNT(*)
--------
1 <-- 총 1건이 DELETE 대상임. DELETE 조건과 MATCHED DATA (MERGE_T1.C1 = 99996)
INSERT 대상확인
USING 절에서 추출한 소스테이블의 데이터 중 타겟 테이블에 존재하지 않고 (st.c2= 'A')조건에 만족하는 소스테이블의 데이터가 INSERT 대상임.
SELECT c1,c2
FROM MERGE_T2
WHERE c1 >= 99990
AND c1 <= 100090
and C2='A'
minus
SELECT c1,c2
FROM MERGE_T1
WHERE c1 >= 99990
AND c1 <= 100090;
C1 C2
------ ---
100022 A
100048 A
100074 A <-- 총 3건이 INSERT 대상임