조건을 만족하는 행이 있으면 UPDATE하고, 그렇지 않으면 INSERT하는 구문입니다.
하지만, SQL Server에서는 UPSERT문을 지원하지 않습니다.
SQL Server 2008 - MERGE 문
SQL Server 2008에 추가된 MERGE 문을 사용하면 하나의 문에서 여러 INSERT, UPDATE 및 DELETE 작업을 수행할 수 있습니다.
단, MERGE문을 잘 못 작성하면 악성 쿼리로 전락하거나, 예기치 않은 동작으로 데이터의 손실을 유발할 수 있으니 익숙하게 사용할 수 있도록 테스트 구문을 많이 작성해 보시기 바랍니다.
MERGE 문으로 UPSERT를 구현
지금까지 SQL Server에서 UPSERT를 수행하려면, UPDATE 후 @@ROWCOUNT를 확인해 다시 INSERT 문을 실행하는 방식을 사용해야 했습니다.
하지만, 이 방식은 자칫 동시성 문제를 유발할 수 있기 때문에 잠금 힌트를 통한 세밀한 트랜잭션 제어를 필요로합니다. 숙련된 개발자에게는 별 문제가 아니겠지만, 안타깝게도 많은 개발자들이 이런 문제를 인식조차 하지 못합니다.
이에 비해 MERGE 문은 단일 문이라 동시성 문제를 크게 고려하지 않아도 될 뿐더러 대개 성능도 더 낫습니다.
Example
IF OBJECT_ID(N'TEST', N'U') IS NOT NULL
DROP TABLE dbo.TEST;
GO
CREATE TABLE dbo.TEST (
seq int IDENTITY(1, 1) NOT NULL,
userSN int NOT NULL,
col1 int NOT NULL
);
GO
INSERT dbo.TEST (userSN, col1)
VALUES (1, 10), (2, 20), (3, 30);
GO
seq |
userSN |
col1 |
1 |
1 |
10 |
2 |
2 |
20 |
3 |
3 |
30 |
-- 1. userSN = 3인 행이 있으면 col1을 300으로 UPDATE하고, 없으면INSERT
MERGE dbo.TEST AS T
USING (SELECT 3, 300) AS S (userSN, col1)
ON T.userSN = S.userSN
WHEN MATCHED THEN
UPDATE SET col1 = S.col1
WHEN NOT MATCHED BY TARGET THEN
INSERT (userSN, col1) VALUES (S.userSN, S.col1);
Results :
seq userSN col1 1 1 10 2 2 20 3 3 300
-- 2. userSN = 4인 행이 있으면 col1을 400으로 UPDATE하고, 없으면INSERT
MERGE dbo.TEST AS T
USING (SELECT 4, 400) AS S (userSN, col1)
ON T.userSN = S.userSN
WHEN MATCHED THEN
UPDATE SET col1 = S.col1
WHEN NOT MATCHED BY TARGET THEN
INSERT (userSN, col1) VALUES (S.userSN, S.col1);
Results :
seq |
userSN |
col1 |
1 |
1 |
10 |
2 |
2 |
20 |
3 |
3 |
300 |
4 |
4 |
400 |
'SQL Server > SQL Server Tip & Tech' 카테고리의 다른 글
How to read SQL Server graphical query execution plans (0) | 2009.11.05 |
---|---|
MERGE 응용 - 2. CTE를 사용한 성능 최적화 (0) | 2009.10.12 |
12 Essential Steps After Installing SQL Server (0) | 2009.08.03 |
SPARSE 컬럼 (0) | 2009.07.30 |
계륵 같은 SNAPSHOT 격리 수준 - SET TRANSACTION ISOLATION LEVEL SNAPSHOT (0) | 2009.07.24 |