< MERGE >
- 조건을 비교해서 테이블에 해당 조건에 맞는 데이터가 없으면 INSERT, 있으면 UPDATE 실행
- 해당 조건을 넣어서 한 문장으로 경우에 따른 처리가 가능
[ 표현법 ]
MERGE INTO 테이블명
USING (UPDATE나 INSERT 될 값)
ON (조건)
WHEN MATCHED THEN
UPDATE
SET 컬럼1 = 값1, 컬럼2 = 값2, ...
WHERE update 조건
* DELETE
WHERE delete 조건
WHEN NOT MATCHED THEN
INSERT (컬럼1, 컬럼2, ...) VALUES (값1, 값2, ...)
WHERE insert 조건
* DELETE 구문 추가 가능
- 사용 예시 1 -
유저에게 정지일자를 부여하는 테이블에
해당 유저가 이미 입력된 적이 있는 경우 UPDATE, 없는경우 INSERT를 부여하기 위해 사용함
<update id="stopMember" parameterType="_int">
merge into penalty
using dual
on (mem_no = #{memNo})
when matched then
UPDATE
SET
END_DATE = SYSDATE + 7
WHERE
MEM_NO = #{memNo}
when not matched then
INSERT (mem_no, end_date)
VALUES
(
#{memNo}
,SYSDATE + 7
)
</update>
- 단일 테이블내에서는 USING에 dual을 넣어 사용
- ON () 안에 일치하는지 확인할 조건을 작성
: 전달한 유저 번호가 매치하는 행이 있는지 확인
- WHEN MATCHED THEN에 매칭되면 수행할 UPDATE문을 작성
: 정지일을 현재 날짜의 7일 이후로 수정
- WHEN NOT MATCHED THEN에 매칭되는 행이 없을 경우 실행할 INSERT문을 작성
: 해당 컬럼에 맞게 유저 번호와 정지일을 입력
- 사용 예시 2 -
스킬을 입력하는 테이블에 스킬 목록(list)을 가지고가서 해당하는 스킬이 없는 경우 INSERT 하기 위해 사용함
<update id="updateSkill" parameterType="list">
MERGE
INTO CODE_SKILL C
USING
(
<foreach collection="list" item="item" index="index" separator="UNION ALL" open="(" close=")">
select #{item} as skill_name from dual
</foreach>
) S
ON (C.SKILL_NAME = S.SKILL_NAME)
WHEN NOT MATCHED THEN
INSERT
VALUES(CODE_SKILL_SEQ.NEXTVAL, S.SKILL_NAME)
</update>
- USING내에 UNION ALL로 묶인 SELECT문(foreach로 생성)을 넣어서 조회되는 값들을 조건에 따라 처리
- CODE_SKILL 테이블에 "C" 별칭, USING에 쓰인 조회값에 "S" 별칭 - 들고간 값은 S에 존재
- WHEN MATCHED THEN UPDATE 구문을 생략하고, 일치하지 않을 때 INSERT문만을 수행하도록 함
* 그렇지만 이렇게 수행했더니 존재하는 기술에도 구문을 실행하게 되면서 code_skill_seq가 발동되어버림...
시퀀스 값이 계속 증가하는 꼴...
'개발 > SQL' 카테고리의 다른 글
[SQL] postgreSQL 설치 및 설정 / pgAdmin 4 (0) | 2023.05.06 |
---|---|
[SQL] Oracle - SEQUENCE (0) | 2022.10.05 |
[SQL] Oracle - VIEW (0) | 2022.10.05 |
[SQL] Oracle - (TCL) 트랜잭션(TRANSACTION) / COMMIT / ROLLBACK / SAVEPOINT (0) | 2022.10.04 |
[SQL] Oracle - (DCL) GRANT / REVOKE (0) | 2022.10.04 |