두 구문은 비슷하다.
해당하는 자료가없으면 INSERT문을 실행하고 있으면 UPDATE문을 사용하는데
구문이 조금 다르다.
# mssql
MERGE INTO table_a AS a
USING (
select
#{A} as B
,#{B} as B
)
AS b
ON (a.A = b.A)
and (a.B = b.B)
WHEN MATCHED THEN
UPDATE
SET a.C = #{C}
,a.D = CURRENT_TIMESTAMP
,a.E = #{E}
WHEN NOT MATCHED THEN
INSERT(
A
,F
)VALUES(
#{A}
,#{F}
);
mssql은 이런식으로 mybatis에서 가져온 데이터를 USING문에서 변수에 넣어준다. 그리고 이 b라고 alias를 선언해주는데 ON절에서 이 조건에 맞는 자료가있으면 조건에 맞는 데이터에 UPDATE문을 실행시켜주고 WHEN NOT MATCHED THEN 즉 일치하지 않을때는 INSERT문을 실행시켜준다.
# postgresql
WITH tbl_with AS (
SELECT #{A} AS A, #{B} AS B, to_char(#{C}::timestamp, 'YYYY-MM-DD') AS C
),
tbl_updated AS (
UPDATE target_table a
SET
A = b.A,
B = b.B,
C = b.C::timestamp
FROM tbl_with b
WHERE
a.A = b.A
AND a.B = b.B
RETURNING a.A, a.B, a.C
),
tbl_inserted AS (
INSERT INTO target_table (
A,
B,
C
)
SELECT
a.A,
a.B,
a.C::timestamp
FROM tbl_with a
WHERE NOT EXISTS (
SELECT *
FROM tbl_updated b
WHERE a.A = b.A
AND a.B = b.B
)
returning A, B
)
SELECT SUM(x.cnt) AS cnt
FROM (
SELECT COUNT(*) AS cnt FROM tbl_updated
UNION ALL
SELECT COUNT(*) AS cnt FROM tbl_inserted
) x;
postgresql의 WITH문도 MERGE문하고 비슷한데 이런식으로 tbl_with문에 가져온 데이터들을 변수에 담아주고 tbl_updated 내에서 WHERE문에 일치하면 UPDATE문을 실행시켜주고 없으면 tbl_updated문에 데이터가 없으므로 아패서 WHERE NOT EXISTS에 아무것도 안뜨게 되어 INSERT문이 실행된다. 참고로 아래 SELECT절에서 CNT절을 꼭 적어줘야 정상적으로 실행이된다.