기본 콘텐츠로 건너뛰기

181010 MERGE INTO

MERGE INTO


0. UPDATE JOIN?

- 2개의 테이블에서 JOIN을 하여 특정 테이블의 column을 수정, 갱신하고자 할 때
- SET절에 sub query형태로 문장을 작성하여 특정 값을 가져오게 하여 UPDATE 시도
예) insert와 update를 동시에:oracle 9i 이후
      insert와 delete를 동시에: oracle 10g 이후

--> BYPASS_UJVC를 통해 UPDATE문을 JOIN
  but, Oracle 11g의 경우 BYPASS_UJVC 힌트가 먹히지 않음

--> MERGE INTO 구문을 사용

1. MERGE INTO 구문

- 조건에 따라서 삽입, 수정, 삭제 작업을 한 번에 처리 가능
- 해당 행이 존재하면 UPDATE 문을 실행, 없다면 INSERT문을 실행
- 대상 table에 대한 UPDATE/INSERT 조건은 ON절에 의해 결정
- ON절에 들어간 컬럼은 UPDATE를 할 수 없음

※ 구문
INTO: data가 UPDATE되거나 INSERT될 table 또는 view를 지정
USING: 비교할 소스 table 또는 view, sub query를 지정
            (비교대상이 없다면 DUAL)
ON: UPDATE나 INSERT하게 될 조건
WHEN MATCHED: ON절에 맞는 ROW가 있을 때, UPDATE나 DELETE
WHEN NOT MATCHED: ON절에 맞는 ROW가 없을 때, INSERT

구문 사용 예1)
MERGE INTO table_name alias
      USING (table | view | subquery) alias       -- 테이블이 1개인 경우는 DUAL을 사용
      ON (join condition)                                         -- WHERE 조건절처럼
      WHEN MATCHED THEN                           -- ON 이하의 조건에 해당하는 데이터가 있는 경우 
           UPDATE SET col1 = val1[, ...]                
      WHEN NOT MATCHED THEN                       -- ON 이하의 조건에 해당하는 데이터가 없는 경우
           INSERT (column lists) VALUES (values);  
cs

구문 사용 예2)
MERGE INTO 타깃 테이블 A
      USING 비교할 소스 테이블 B         -- 동일한 테이블인 경우는 DUAL
         ON (A.필드1 = B.필드1 
         AND A.필드2 = B.필드2 ...) 
      WHEN MATCHED THEN                 -- 존재하면 UPDATE UPDATE 
       SET A.타깃_필드1 = B.소스_필드1 
          ,A.타깃_필드2 = B.소스_필드2 
      WHEN NOT MATCHED THEN             -- 없으면 INSERT 
      INSERT (타깃_필드1
            , 타깃_필드2
            , 타깃_필드3 ...) 
      VALUES( B.소스_필드1 
            , B.소스_필드2 
            , B.소스_필드3 ... );
 
cs

2. 사용

MERGE INTO FA_WHTX_SEND_HSTR A
         USING DUAL
             ON (
                 A.CMPN_CD      = #{cmpnCd}
            AND A.PROJ_CD     = #{projCd}
            AND A.SLIP_NO        = #{slipNo} 
            AND A.SLIP_LINE_NO  = #{slipLineNo}
            AND A.SEND_DVSN_CD = #{sendDvsnCd}       
               )
    WHEN MATCHED THEN
           UPDATE SET
                    A.EML_SEDR  = #{emlSedr, jdbcType=VARCHAR}          
                  , A.EML_SEND_DT = SYSDATE             
                  , A.EML_RCVR     = #{recvEml, jdbcType=VARCHAR}           
                  , A.REG_DTM      = SYSDATE             
                  , A.RGSR_ID      = #{rgsrId}           
                  , A.MDF_DTM     = SYSDATE             
                  , A.MDFR_ID      = #{mdfrId}           
    WHEN NOT MATCHED THEN
           INSERT (
                     CMPN_CD
                , PROJ_CD
                , SLIP_NO
                , SLIP_LINE_NO
                , SEND_DVSN_CD
                , EML_SEDR
                , EML_SEND_DT
                , EML_RCVR
                , REG_DTM
                , RGSR_ID
                , MDF_DTM
                , MDFR_ID
                 )
           VALUES(
                     #{cmpnCd}
                   , #{projCd}
                   , #{slipNo} 
                   , #{slipLineNo}
                   , #{sendDvsnCd}
                   , #{emlSedr, jdbcType=VARCHAR}
                   , SYSDATE
                   , #{recvEml, jdbcType=VARCHAR}
                   , SYSDATE
                   , #{rgsrId}
                   , SYSDATE
                   , #{mdfrId}
                    )
cs