본문 바로가기

업무/ORACLE

선택적 트렌젝션처리 Merge

create table merge_test
(
year char(4),
month char(4),
val NUMBER(13,0),
stxt vharchar(10)
);

alter table MERGE_TEST add constraint PKX_MERGE_TEST primary key (year,month);

insert into MERGE_TEST values ('2005', '01', 123, '생성');
insert into MERGE_TEST values ('2005', '04', 92, '생성');
insert into MERGE_TEST values ('2005', '09', 31 '생성');
commit;


select /*+INDEX_ASC(a)*/ a.* from MERGE_TEST a
---------------------------------
YEAR MONTH VAL STXT
---------------------------------
2005 01 123 생성
2005 04 92 생성
2005 09 31 생성
----------------------------------

-- 데이터 변경
update table MERGE_TEST set VAL=94, STXT = '변경' where YEAR='2005'and MONTH='09';
commit;

select /*+INDEX_ASC(a)*/ a.* from MERGE_TEST a
---------------------------------
YEAR MONTH VAL STXT
---------------------------------
2005 01 123 생성
2005 04 92 생성
2005 09 94 변경
----------------------------------

merge into MERGE_TEST b
using (
select '2005' as YEAR, '01' as MONTH, 111 as VAL from DUAL
union
select '2005' as YEAR, '02' as MONTH, 222 as VAL from DUAL
union
select '2005' as YEAR, '03' as MONTH, 333 as VAL from DUAL
union
select '2005' as YEAR, '04' as MONTH, 444 as VAL from DUAL
) a
on (a.YEAR = b.YEAR and a.MONTH = b.MONTH)
when matched then
update set b.VAL = a.VAL, STEXT = '변경'
when not matched then
insert values (a.YEAR, a.MONTH, a.VAL, '생성')

commit;

select /*+INDEX_ASC(a)*/ a.* from MERGE_TEST a
---------------------------------
YEAR MONTH VAL STXT
---------------------------------
2005 01 111 변경 < merge>>update 가 적용됨
2005 02 222 생성 < merge>>insert 가 적용됨
2005 03 333 생성 < merge>>insert 가 적용됨
2005 04 444 변경 < merge>>update 가 적용됨
2005 09 94 변경
----------------------------------

출처:PHP School

머지문을 이용하는 주된 이유가,,, update 와 insert 를 선택적으로 해야하는 상황..
예를들면, 이미 테이블에 데이터가 있는경우 UPDATE를
데이터가 없는경우, INSERT 를 해야할경우
업무하다보면 이런 트랜잭션은, 상당히 많이 발생합니다.....
insert 나 update 를 따로 운용할경우, 데이터가 있는지
미리 체크를 해줘야하므로, 이를 체크하는 부분을 포함시켜
줘야하는데,
merge 를 이용하면, 이것을 단 하나의 메서드로 구현할수있음