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. 안전성
- 동시성 문제를 방지한다.