본문 바로가기
2.2 DB/ORACLE

[Oracle/SQL] MERGE INTO

by Dohi._. 2024. 7. 30.
728x90

MERGE INTO 문

UPDATE문, INSERT문, DELETE문 등을 상황에 따라 나눠서 처리하는 문장으로
주로 동일한 데이터가 있을경우 UPDATE, 없을경우 INSERT를 하기 위해 사용된다.

MERGE 
 INTO 테이블1 -- 테이블,뷰
USING 테이블2 -- 테이블,뷰,서브쿼리,dual
   ON 조건   -- 매칭 조건 ( PK 또는 UNIQUE 제약조건을 사용)
WHEN MATCHED THEN --조건 ture (UPDATE,DELETE) , 조건 true일때 아무것도 안하고 싶다면 없어도됨
    UPDATE
       SET 컬럼 = 값
       -- WHERE절 사용가능(오라클10g이후 INSERT는 X)

WHEN NOT MATCHED THEN --조건 false (INSERT), 조건 false일때 아무것도 안하고 싶다면 없어도됨
    INSERT (컬럼1, 컬럼2, ...) -- 삽입할 컬럼 목록
    VALUES (값1, 값2, ...) -- 삽입할 값

 

UPDATE문과 INSERT문은 주로 아래와 같이 이루어져있는데 위에있는 MERGE문에있는 거와 다를것이다.

UPDATE 테이블 SET 컬럼 = 값 WHERE 조건;
INSERT INTO 테이블(컬럼1, 컬럼2, ...) VALUES (값1, 값2, ...); 

MERGE INTO문의 테이블1에 수정,추가,삭제가 이루어지기때문에 merge문의 update,insert에는 테이블1이 명시되어있는 셈이다.


상황 적용예제

1.SQL (DUAL)

MERGE INTO AP a
    USING DUAL
       ON (a.user_id  = 'aaa')
    WHEN MATCHED THEN
        UPDATE SET a.testcode = 20
    WHEN NOT MATCHED THEN
        INSERT ( a.user_id, a.testcode)
        VALUES ('S1',20)
        
        ;

 

2. 데이터 옮기기  COPY_AP -> AP

MERGE INTO AP a
    USING COPY_AP c
       ON (a.user_id  = c.user_id)
    WHEN MATCHED THEN
        UPDATE SET a.testcode = c.testcode
    WHEN NOT MATCHED THEN
        INSERT ( a.user_id, a.testcode)
        VALUES ( c.user_id, c.testcode) 
        ;
        
    /* copy -> AP*/

 

 

3. 실제적용 (PL/SQL)

if문을 이용해서 데이터 존재여부를 확인하던 코드를 MERGE로 변경할경우

해당코드는 COUNT를 통해 확인하는 코드입니다 

-- 적용전
PROCEDURE test_insert(
                           in_user_id       in   varchar2   
                        ,  in_testcode      in   varchar2 
                        )
IS
    v_AP AP%rowtype;
    cnt number;

BEGIN
    BEGIN
         SELECT count(*)
          INTO cnt
          FROM AP
         WHERE user_id = in_user_id;

        IF v_cnt > 0 then
            BEGIN
                UPDATE AP
                   SET      dte    := sysdate;
                       , testcode  := in_testcode;
                 WHERE   user_id    = in_user_id;
        END;
        ELSE
            BEGIN
                v_AP.user_id   := in_user_id;
                v_AP.dte       := sysdate;
                v_AP.testcode  := in_testcode;
                INSERT 
                  INTO AP 
                  VALUES v_AP;
            END;
        END IF;
    end;
end;

 

IF문대신 MERGE INTO를 통해서 더욱 간단해졌습니다.

-- 적용이후
PROCEDUER test_merge(
                           in_user_id          in   varchar2   
                        ,  in_testcode         in   varchar2 
                        )
is
    v_AP AP%rowtype;
BEGIN
    BEGIN
        v_AP.user_id    := in_user_id;
        v_AP.dte           := sysdate;
        v_AP.testcode   := in_testcode;

        MERGE 
        INTO AP A
        USING DUAL 
           ON (A.user_id = v_AP.user_id)
        WHEN MATCHED THEN
              UPDATE -- 주의할점 ON에 있는 user_id 컬럼을 UPDATE하면 오류발생한다. 
                 SET dte         = v_AP.dte
                   , testcode  = v_AP.testcode;
        WHEN NOT MATCHED THEN
              INSERT
              VALUES  v_AP;
    END;
END;

 

728x90

'2.2 DB > ORACLE' 카테고리의 다른 글

[oracle] Union / Union ALL  (0) 2024.09.30
[Oracle] null 처리 함수 (NVL, NVL2)  (0) 2024.09.26
[Oracle/SQL] 날짜 마지막 시간 적용에 0.99999 쓰는 이유  (3) 2024.09.25
[ORACLE] 테이블 복제  (0) 2024.09.23
[Oracle/SQL] With 절  (0) 2024.07.30

댓글