본문 바로가기
Database/MSSQL

MERGE 구문

by 잘먹는 개발자 에단 2025. 6. 26.
MERGE dbo.e_uservideoprogress AS target
USING (SELECT @employeeid AS employeeid, @videoid AS videoid) AS source
ON (target.employeeid = source.employeeid AND target.videoid = source.videoid)
    WHEN MATCHED THEN
        UPDATE SET 
            watchedtime = @watchedtime,
            iscompleted = @iscompleted,
            lastwatchedat = @lastwatchedat
    WHEN NOT MATCHED THEN
        INSERT (employeeid, videoid, watchedtime, iscompleted, lastwatchedat, year)
        VALUES (@employeeid, @videoid, @watchedtime, @iscompleted, @lastwatchedat, YEAR(GETDATE()));

 

1. Merge 구문의 구조

Merge dbo.e_uservideoprogress AS target

- target : 업데이트하거나 삽입할 테이블이 대상이다.

- 여기에서는 e_uservideo progress 테이블이 대상이다.

 

USING ( SELECT @employeeid AS employeeid, @videoid AS videoid ) AS source

- source : 비교할 소스데이터이다.

- 여기서는 입력받은 employeeid와 videoid값을 가상의 테이블로 만든다.

 

2. 조건매칭

ON (target.employeeid = source.employeeid AND target.videoid = source.videoid )

- 대상 테이블과 소스 데이터를 어떤 조건으로 비교할지 정의한다.

- employeeid와 videoid가 모두 일치하는 레코드를 찾는다.

 

3. 매칭된 경우 처리 

WHEN MATCHED THEN UPDATE SET...

- 이미 존재하는 레코드가 있을 때 실행된다.

- 해당 레코드의 값들을 새로운 값으로 업데이트 한다.

- 업데이트 되는 컬럼들 watchedtime, iscompleted, lastwatchedat

 

4. 매칭되지 않은 경우의 처리

WHEN NOT MATCHED THEN INSERT

- 존재하지 않는 레코드일 때 실행된다.

- 새로운 레코드를 삽입한다.

- 삽입되는 컬럼들

- employeeid, videoid

- watchedtime, iscompleted, lastwatchedat

- year : YEAR(GETDATE())로 현재년도 자동입력

 

 

동작 예시

1. 기존 데이터가 있다면

기존 데이터: employeeid='EMP001', videoid=123, watchedtime=300
새 데이터: employeeid='EMP001', videoid=123, watchedtime=600

결과: 기존 레코드의 watchedtime이 300 → 600으로 업데이트!!

 

2. 기존 데이터가 없다면

새 데이터: employeeid='EMP002', videoid=456, watchedtime=200

결과: 새로운 레코드가 삽입됩니다!!

 

 

 

MERGE 구문의 장점

1. 원자성 

- 한번의 쿼리로 INSERT 또는 UPDATE가 결정된다.

2. 성능

- 별도의 SELECT 문으로 존재여부를 확인할 필요가 없음. 

3. 안전성

- 동시성 문제를 방지한다.