본문 바로가기
DBMS/Oracle

[Oracle] ORACLE - MERGE INTO 구문

by 성은2 2021. 6. 29.

DB 조회하여 특정 테이블에 조건이 일치할 경우 UPDATE,

일치하지 않을 경우 INSERT.

 

예를 들어 이미 저장된 회원정보가 있으면 UPDATE, 초기 저장이기 때문에 없을 경우 INSERT 구문을 실행하는 것이다.

비즈니스 로직으로 분기처리할 수 있지만, Oracle에서는 MERGE INTO 구문을 사용하면 하나의 로직으로 처리 가능하다.

 

구문

더보기

MERGE INTO

Insert or Update 할 타겟 테이블

USING 

타켓 테이블에 들어갈 데이터(ex : 테이블 ,뷰, 서브쿼리, DUAL도 사용가능)

ON (

INSERT할 것인지 UPDATE 할것인지를 결정하는 조건 

즉, ON절에 기술된 조건이 일치하면 업데이트문 실행

조건이 맞지 않으면 인서트 문을 실행한다.

primary key가 ON 절의 조건으로 와야하며, ON 조건절에 사용된 컬럼은 UPDATE가 불가능하다.  

)

WHEN MATCHED THEN  

조건이 맞았을 때 쿼리문(ex : 컬럼 update)

WHEN NOT MATCHED THEN 

조건이 맞지 않았을 때 쿼리문 (ex : 데이터  insert OR delete)

- 생략가능 

- MATCHED나 NOT MATCHED 하나씩만도 사용가능

 

 

 

예시 2 

MERGE INTO INFO_TABLE A
USING (
	SELECT '2021' AS YEAR
              ,'1234' AS CODE
              ,'1943_21' AS INFO_CODE
              ,'01' AS VER
	FROM DUAL; 
	) B
ON (
	A.YEAR = B.YEAR
	AND A.CODE = B.CODE
	AND A.INFO_CODE = B.INFO_CODE
	// ON절에 나오는 매칭 조건은 주키(primary key)를 사용한다. 그렇지 않으면 데이터 중복이 발생할 수 있다.
	// ON 조건절에 사용된 컬럼은 UPDATE가 불가능
	// INFO_TABLE의 경우 PK가 YEAR, CODE, INFO_CODE이다.
   )
WHEN MATCHED THEN 
	// 조건이 맞을시 실행할 구문, 테이블 혹은 조회한 서브쿼리 데이터 사용가능.
	UPDATE SET CODE = B.CODE
         , VER = B.VER
         , INFO_CODE = B.INFO_CODE
         , USERID = '${userId}' // mybatis에서 받아온 parameter
         , UDATE = SYSDATE
WHEN NOT MATCHED THEN 
	// 조건이 틀릴시 실행할 구문, when not matched 구문은 생략가능
	INSERT (CODE, VER,  INFO_CODE, USERID, SYSDATE)
    // 응용 :parameter를 넘겨서 insert해도 됨
	VALUES ('5678_21', '02', '002','se.shin', SYSDATE )

 

 

 

 

 

예시 2 

★ UNION ALL 구문 -  임시로 만든 데이터를 INSERT할 수 있다.

MERGE INTO TOP_MID_ARRAY A
USING (
	// 필요한 데이터를 UNION ALL해서 DUAL로 만든 SELECT 구문
             SELECT '2022' AS YEAR
                  ,'3' AS TYPE
                  ,'3' AS FULLFILL_SEQ
               FROM DUAL
              UNION ALL 
              SELECT '2021' AS YEAR
                 , '3' AS TYPE
                 , '1' AS FULLFILL_SEQ
            	FROM DUAL   
			  UNION ALL 
           	 SELECT '2020' AS YEAR
                , '3' AS TYPE
                , '2' AS FULLFILL_SEQ
         		FROM DUAL 
     ) B
ON (  
       A.YEAR = B.YEAR 
       AND A.TYPE = B.TYPE
       AND A.FULLFILL_SEQ = B.FULLFILL_SEQ
   )
WHEN MATCHED THEN
	// USING 절에서 DUAL로 만든 데이터로 update.
    // USING절에서 SELECT된 데이터는 Alias로 접근해서 사용 가능하다. ex) B.xxx
    UPDATE SET LEVEL = B.LEVEL
    , FULLFILL_PERM = B.FULLFILL_PERM
    , START_POINT = B.START_POINT
    , END_POINT = B.END_POINT
    , UDATE = SYSDATE
    , UUSER = 'KIM'          
WHEN NOT MATCHED THEN
   INSERT (YEAR, TYPE, FULLFILL_SEQ, LEVEL, FULLFILL_PERM, START_POINT, END_POINT, RUSER, RDATE)
   VALUES (
              B.YEAR, B.TYPE, B.FULLFILL_SEQ, B.LEVEL, B.FULLFILL_PERM, B.START_POINT
            , B.END_POINT, B.RUSER, B.RDATE
          );

 

 

 

 

 

https://offbyone.tistory.com/253

 

오라클 MERGE INTO 문으로 있으면 UPDATE 없으면 INSERT 한번에 수행하기

테이블에 데이터가 이미 존재하면 업데이트 하고, 존재하지 않으면 입력을 해야 하는 경우가 종종 있습니다. 오라클에서 이런 작업을 한번에 할 수 있는 쿼리가 MERGE INTO 문 입니다. 현실적인 예

offbyone.tistory.com