홈 › SQL 고급 › 08 / 10

MERGE 와 UPSERT

있으면 수정, 없으면 입력
섹션 6진행 0 / 10

2. 핵심 원리

2.1 MERGE 의 구조

sql
MERGE INTO 대상 t
USING 원천 s
   ON (t.키 = s.키)
 WHEN MATCHED THEN
      UPDATE SET ...
 WHEN NOT MATCHED THEN
      INSERT (...) VALUES (...);

USING 의 원천은 테이블이나 서브쿼리이고, ON 조건으로 원천의 각 행이 대상의 어느 행과 짝이 되는지 정합니다. 짝이 있으면 WHEN MATCHED, 없으면 WHEN NOT MATCHED 가 실행됩니다. 원천 한 행이 대상 한 행에 대응하는 것이 전제입니다.

원천 행 대상에 짝이 실행되는 절
있음 있음 WHEN MATCHED
있음 없음 WHEN NOT MATCHED
없음 있음 표준 MERGE 에는 없음(MSSQL 은 BY SOURCE)
핵심

MERGE 는 원천의 각 행을 대상과 ON 으로 맞춰 보고, 짝이 있으면 UPDATE, 없으면 INSERT 합니다. 원천에 같은 키가 여러 건이면 안 됩니다.

2.2 DB 별 지원

기능 Oracle·Tibero MySQL MSSQL
MERGE 9i 부터 없음 2008 부터
하나의 WHEN 만 사용 10g 부터 - 가능
UPDATE 뒤 WHERE, DELETE WHERE 10g 부터 - 없음(AND 조건, THEN DELETE 사용)
대상에만 있는 행 처리 없음 - WHEN NOT MATCHED BY SOURCE
처리 내역 반환 없음 - OUTPUT $action
UPSERT 대안 - ON DUPLICATE KEY UPDATE -

Oracle 9i 는 WHEN MATCHED 와 WHEN NOT MATCHED 를 둘 다 써야 했고, 10g 부터 하나만 써도 됩니다. MSSQL 은 2008 부터 지원하며 MERGE 문 끝에 세미콜론이 필수입니다. Tibero 도 MERGE 를 지원합니다.

2.3 MySQL 의 세 가지

MySQL 은 PRIMARY KEY 나 UNIQUE 충돌이 났을 때 어떻게 할지를 INSERT 문에 붙입니다. 충돌 기준이 ON 조건이 아니라 키 제약이라는 점이 MERGE 와 다릅니다.

문법 충돌한 행 새 행
INSERT ... ON DUPLICATE KEY UPDATE 지정한 컬럼만 UPDATE INSERT
INSERT IGNORE 건너뜀(그대로) INSERT
REPLACE INTO DELETE 후 INSERT INSERT

REPLACE 는 이름과 달리 "수정" 이 아니고 지우고 다시 넣는 것이라, INSERT 에서 지정하지 않은 컬럼은 기본값(없으면 NULL)이 됩니다. 자식 테이블이 이 행을 참조하면 삭제 단계에서 외래 키 오류나 연쇄 삭제가 일어날 수 있습니다.