테이블에 데이터가 이미 있으면 UPDATE 를 실행하고, 없을 경우 값을 INSERT 해줘야 하는 경우에 MERGE INTO 문을 통해 한 쿼리로 간단하게 작성할 수 있다.
* 오라클 9i 버전 이상부터 사용 가능 (but 10g이상 사용 추천)
아래와 같이 사용한다.
MERGE INTO "테이블 명"
USING "테이블 or 뷰 or 서브쿼리"
ON (
" 조건절1"
AND " 조건절2 "
...
) -- 값이 있는지 확인
WHEN MATCHED THEN --있으면
UPDATE SET
[COLUMN1] = [VALUE1],
[COLUMN2] = [VALUE2],
WHEN NOT MATCHED THEN --없으면
INSERT (COLUMN1, COLUMN2, ...)
VALUES (VALUE1, VALUE2, ...)
단일 테이블로 사용할때, dual 사용
* dual : 오라클 자체에서 제공되는 테이블, 오직 한행, 한컬럼을 담고 있는 dummy 테이블
MERGE
INTO emp a
USING dual
ON (a.empno = 7788)
WHEN MATCHED THEN
UPDATE
SET a.deptno = 20
WHEN NOT MATCHED THEN
INSERT (a.empno, a.ename, a.deptno)
VALUES (7788, 'SCOTT', 20);
USING 절에 테이블 대신 dual을 사용하면 된다. ON 조건절이 일치하면 UPDATE, 불일치하면 INSERT를 하는 쿼리이다.
emp 라는 테이블에 empno값이 7788이면, update문 실행하고 아니면 insert문 실행한다.
실제로 개발할때 아래와 같이 사용했다.
MERGE INTO "부서테이블" USING DUAL ON (
LOC_GOV_CD = ?
AND GOV_OFFICD_CD = ?
...
)
WHEN MATCHED THEN
UPDATE SET
LOC_GOV_CD = ?
AND GOV_OFFICD_CD = ?
...
CHG_DT = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MMSS'),
...
WHEN NOT MATCHED THEN
INSERT (
LOC_GOV_CD,
...
) VALUES (
?
...
)
- USING ~ ON ( "조건절" ) -> 조건절에 사용한 컬럼은 UPDATE 불가능함. 따라서 PK로 비교
- DELETE 문도 사용 가능 (오라클 10g 이상 가능) 따라서 오라클 10g이상일 경우만 MERGE 문 사용하는게 좋음.
* 단점?
- 성능 문제
처음 작업속도는 빠르지만, 시간이 지날수록 작업속도가 느려지므로 인덱스 전략을 잘 수립해서 사용 필요
대용량 처리 할 경우 CPU 점유율 높아져 부하발생 -> 중소규모작업 (10만건 이하) 일 경우 유용함.
- DB 변경될 경우가 있을까?
변경되는 DB에 MERGE문 없으면 소스 변경 공수 많이듬. 그래서 범용적인 쿼리문 사용하는게 좋음 (그럴 경우가 많을까?)
- 쿼리 리펙토링 문제가 있나?
나중에 쿼리 리펙토링 할때 어려울 것 같음. SELECT이후 분기처리 하는게 리펙토링 면에서 유리할 것이다.
상황에 따라 맞게 쓰면 될 것 같다.
Ref.
'Backend > Database' 카테고리의 다른 글
[Oracle] 오라클과 JDBC 연결하는 방법 (11g 엔터프라이즈 버전) (3) | 2021.01.18 |
---|---|
[Oracle] 오라클의 구조 (0) | 2021.01.15 |
[Oracle] SQL plus 에서 계정 등록 및 권한 설정 (0) | 2021.01.14 |
[Oracle] HTTP Listener Port 변경하기 (0) | 2021.01.14 |