본문 바로가기

프로그래밍팁/oracle

[oracle]MERGE INTO 로 여러ROW 한꺼번에 UPDATE 및 INSERT

반응형

MERGE INTO로 해당하는 테이블에 조건에 해당하는 값이 있으면 UPDATE를 진행하고 없으면 INSERT로 값을 입력해 주는 방법 입니다. 생각보다 간단하고 쓸 일이 많기 때문에 적어 보도록 할게요. 우선 ORACLE 10G 이상에서 사용을 권장하고, WITH로 하는 방법도 있지만, 적극 추천하는 방법은 MERGE INTO 입니다. 하나씩 살펴 보도록 하죠.

 

1. 기본구조 : T테이블에 UPDATE또는 INSERT를 할건데 A와B테이블의 값들로 합니다. KEY가 되는 값이 있으면 UPDATE, 없으면 INSERT를 하는 구조 입니다.

MERGE INTO TTR_TABLE T
USING (
        SELECT A.R_ID     AS R_ID
               ,A.R_DT    AS R_DT
               ,A.R_NM    AS R_NM
               ,A.R_IN_J  AS R_IN_J
               ,A.R_TN    AS R_TN
               ,B.R_BN    AS R_BN
          FROM TTA_TABLE A
               ,TTB_TABLE B
         WHERE 1=1
           AND A.R_ID = B.R_ID
           AND A.R_DT BETWEEN '20200101' AND '20201231'
         GROUP BY A.R_ID
               ,A.R_DT
       ) S
    ON (T.P_ID = S.R_ID
   AND T.P_DT = S.R_DT)
  WHEN MATCHED THEN
UPDATE SET
       T.P_NM = S.R_RM
       ,T.P_IN_J = S.R_IN_J
       ,T.P_TN = S.R_TN
       ,T.P_BN = S.R_BN
  WHEN NOT MATCHED THEN
INSERT ( P_ID
        ,P_DT
        ,P_NM
        ,P_IN_J
        ,P_TN
        ,P_BN)
       VALUES (S.R_ID
               ,S.R_DT
               ,S.R_NM
               ,S.R_IN_J
               ,S.R_TN
               ,S.R_BN)
;

 

2. 어떤 값을 UPDATE또는 INSERT할지 SELECT문 부터 살퍄 보도록 하죠. 어떤 값들을 넣어줄지 얼마나 되는지 확인하는 작업도 되고 하나씩 쪼개서 보아야 실수를 줄일 수 있죠. USING의 괄호 안에 있는 부분 입니다.

        SELECT A.R_ID     AS R_ID
               ,A.R_DT    AS R_DT
               ,A.R_NM    AS R_NM
               ,A.R_IN_J  AS R_IN_J
               ,A.R_TN    AS R_TN
               ,B.R_BN    AS R_BN
          FROM TTA_TABLE A
               ,TTB_TABLE B
         WHERE 1=1
           AND A.R_ID = B.R_ID
           AND A.R_DT BETWEEN '20200101' AND '20201231'
         GROUP BY A.R_ID
               ,A.R_DT
  

where조건에 1=1은 모든 조건이 일치한지 확인하는 그문이고, and조건에 R_ID가 A와 B모두에 있고 날짜는 20200101~20201231까지로 합니다. 이 조건에 해당하는 데이터들이 있는지 조회를 해 보고 조건이 맞는지도 확인합니다. 

 

3. 조회된 내역이 맞다면 ON부분에 있는 조건들이 있으면 (WHEN MATCHED THEN) UPDATE를 하고 없으면(WHEN NOT MATCHED THEN) INSERT를 합니다. 

 

※만약 둘 중에 하나의 조건만 원한다면 하나의 조건절을 삭제하고 진행하면 됩니다. UPDATE만 원하면 WHEN NOT MATCHED THEN 부분부터 아래의 내용을 삭제하면 되고, 반대의.경우는 WHEN MATCHED THEN 부분부터 WHEN NOT MATCHED THEN 부분 전 까지 삭제를 하면 됩니다. 

 

/*업데이트만 할 경우*/
MERGE INTO TTR_TABLE T
USING (
        SELECT A.R_ID     AS R_ID
               ,A.R_DT    AS R_DT
               ,A.R_NM    AS R_NM
               ,A.R_IN_J  AS R_IN_J
               ,A.R_TN    AS R_TN
               ,B.R_BN    AS R_BN
          FROM TTA_TABLE A
               ,TTB_TABLE B
         WHERE 1=1
           AND A.R_ID = B.R_ID
           AND A.R_DT BETWEEN '20200101' AND '20201231'
         GROUP BY A.R_ID
               ,A.R_DT
       ) S
    ON (T.P_ID = S.R_ID
   AND T.P_DT = S.R_DT)
  WHEN MATCHED THEN
UPDATE SET
       T.P_NM = S.R_RM
       ,T.P_IN_J = S.R_IN_J
       ,T.P_TN = S.R_TN
       ,T.P_BN = S.R_BN
;

/*인서트만 할 경우*/
MERGE INTO TTR_TABLE T
USING (
        SELECT A.R_ID     AS R_ID
               ,A.R_DT    AS R_DT
               ,A.R_NM    AS R_NM
               ,A.R_IN_J  AS R_IN_J
               ,A.R_TN    AS R_TN
               ,B.R_BN    AS R_BN
          FROM TTA_TABLE A
               ,TTB_TABLE B
         WHERE 1=1
           AND A.R_ID = B.R_ID
           AND A.R_DT BETWEEN '20200101' AND '20201231'
         GROUP BY A.R_ID
               ,A.R_DT
       ) S
    ON (T.P_ID = S.R_ID
   AND T.P_DT = S.R_DT)
  WHEN NOT MATCHED THEN
INSERT ( P_ID
        ,P_DT
        ,P_NM
        ,P_IN_J
        ,P_TN
        ,P_BN)
       VALUES (S.R_ID
               ,S.R_DT
               ,S.R_NM
               ,S.R_IN_J
               ,S.R_TN
               ,S.R_BN)
;