MERGE [ hint ]
INTO [ schema. ] { table | view } [ t_alias ]
USING { [ schema. ] { table | view }
| subquery
} [ t_alias ]
ON ( condition )
WHEN MATCHED THEN
UPDATE SET column = { expr | DEFAULT }
[, column = { expr | DEFAULT } ]...
[ DELETE where_clause ]
WHEN NOT MATCHED THEN
INSERT [ (column [, column ]...) ]
VALUES ({ expr [, expr ]... | DEFAULT })
아래 예제는 부서번호 20,30의 사원이 존재하면 급여를 10% 인상하고, 존재하지 않으면 급여가 1000보다 큰 사원정보를 등록하는 예이다. (INSERT, UPDATE 예제)
-- 부서번호 10, 20의 사원정보를 가지는 테스트 테이블을 생성하자
CREATE TABLE emp_merge_test
AS SELECT empno, deptno, sal FROM emp WHERE deptno IN (10, 20);
-- 데이터를 확인해 보자
SELECT * FROM emp_merge_test;
-- 사원이 존재하면 급여를 10% 인상하고, 없으면 INSERT 한다.
MERGE INTO emp_merge_test m
USING ( SELECT empno, deptno, sal -- USING절에 뷰가 올수 있다.
FROM emp
WHERE deptno IN (20,30)) e
ON ( m.empno = e.empno)
WHEN MATCHED THEN
UPDATE SET m.sal = ROUND(m.sal*1.1)
WHEN NOT MATCHED THEN
INSERT (m.empno, m.deptno, m.sal)
VALUES (e.empno, e.deptno, e.sal)
WHERE e.sal > 1000 -- INSERT 절의 조건절도 지정이 가능하다
COMMIT;
-- 20부서의 급여가 10%증가했고, 30부서는 등록되었는지 확인해 보자
SELECT * FROM emp_merge_test;
-- 다음 테스트를 위해서 emp_merge_test 테이블에 30부서 데이터를 삭제하자
-- 부서번호 10과 20의 사원정보만 남을 것이다.
DELETE FROM emp_merge_test WHERE deptno = 30;
COMMIT;
아래는 부서번호 10의 사원 급여를 10% 인상하고, 부서번호 20의 사원정보는 삭제하며, 부서번호 30의 사원 급여를 20% 인상하는 예이다. (INSERT, UPDATE, DELETE 예제)
-- 30 부서가 삭제되었는지 확인한다. SELECT * FROM emp_merge_test; -- MERGE 문 작성 MERGE INTO emp_merge_test m USING emp e ON (m.empno = e.empno) WHEN MATCHED THEN UPDATE SET m.sal = ROUND(m.sal*1.1) DELETE WHERE (m.deptno = 20) -- 부서번호 20의 사원정보는 삭제. WHEN NOT MATCHED THEN INSERT (m.empno, m.deptno, m.sal) VALUES (e.empno, e.deptno, ROUND(e.sal*1.2)); COMMIT; -- 정상적으로 변경되었는지 확인해 보자 SELECT * FROM emp_merge_test; -- 테스트 테이블은 삭제하자 DROP TABLE emp_merge_test;
- 강좌 URL : https://www.gurubee.net/lecture/2225
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.
작살 / 상위 버전 오라클에서 돌려보세요. 또는 하위 버전에서도 힌트 부분을 가상 테이블과 관계를 두면 처리가 됩니다. 하위 버전에서는 버그라기 보다 관계 중심으로 명확하게 짜지 않으면 에러는 없는데 분기가 아무데도 안되는 경우가 있습니다.
로드맵 정주행중입니다.
좋은게시물 감사합니다.
MERGE 예제2 의 11 번라인
UPDATE SET m.sal = ROUND(m.sal*1.1)
DELETE WHERE (m.deptno = 20) -- 부서번호 20의 사원정보는 삭제
update 와 delete 두가지가 동시에 안되는데요.. 9i 입니다.
10g 부터 delete 문이 추가 된듯 합니다..^^
머지하게 되네요 머지문 ㅋㅋ 잘 배워갑니다 첨보는거라 오잉하지만..
저는 예제1번에서 부터 ora-30926 에러가 나네요..
on절에 쿼리가 잘못된건가요??;;;
앗, 해결했습니다 제 emp테이블에 문제가 있었네요...ㅠㅠ
MERGE INTO emp_merge_test mUSING emp eON (m.empno = e.empno)WHEN MATCHED THEN UPDATE SET m.sal = ROUND(m.sal*1.1) where m.dept = 10 DELETE WHERE (m.deptno = 20) -- 부서번호 20의 사원정보는 삭제.WHEN NOT MATCHED THENINSERT (m.empno, m.deptno, m.sal)VALUES (e.empno, e.deptno, ROUND(e.sal*1.2));COMMIT;MERGE 에서의 DELETE 구문은
DELETE 단독 구문이 아닌 UPDATE 구문에 종속됩니다.
UPDATE 실행된 건에 한해서 DELETE 구문 동작합니다.
따라서 10번부서는 Update 20번부서는 Delete 하려면
Update 구문의 Where 절을 다음과 같이 바꿔주시면 됩니다.
WHERE m.deptno IN (10, 20)
안녕하세요 초보자입니다..
예제2번이요
ㄱ - 아래는 부서번호 10의 사원 급여를 10% 인상하고
ㄴ - 부서번호 20의 사원정보는 삭제하며
ㄷ - 부서번호 30의 사원 급여를 20% 인상하는 예이다.
ㄱㄴㄷ 중에 ㄴ 만 이해가되네요.. 도와주세요..
* WHEN MATCHED : ON 조건절이 TRUE 인 ROW에 수행 할 내용 (UPDATE, DELETE 포함될수있음)
* WHEN NOT MATCHED : ON 조건절에 맞는 ROW가 없을 때 수행할 내용 (INSERT)
ㄱ > 부서번호 10의 사원급여를 10% 인상인데 10이라는 조건이 어디있나요 ?
ㄷ > 부서번호 30의 사원급여를 20% 인상인데 부서번호 30이라는조건이 어디에있는지..
ON 절에 m.empno=e.empno 만으로는 잘이해가안되네요 .. 도와주세요
예제2)
MERGE INTO emp_merge_test m
USING emp e
ON (m.empno = e.empno)
WHEN MATCHED THEN
UPDATE SET m.sal = ROUND(m.sal*1.1)
DELETE WHERE (m.deptno = 20) -- 부서번호 20의 사원정보는 삭제.
WHEN NOT MATCHED THEN
INSERT (m.empno, m.deptno, m.sal)
VALUES (e.empno, e.deptno, ROUND(e.sal*1.2));
안녕하세요 1년가까이 시간이 지났는데, 제가 이해한것을 바탕으로 적어볼께요 .(이후에 볼사람들을 위해 ㅎㅎ)
ㄱ - 아래는 부서번호 10의 사원 급여를 10% 인상하고
ㄴ - 부서번호 20의 사원정보는 삭제하며
ㄷ - 부서번호 30의 사원 급여를 20% 인상하는 예이다.
-------------------------------------------------------------------------------------
ㄱ > 부서번호 10의 사원급여를 10% 인상인데 10이라는 조건이 어디있나요 ?
-> UPDATE SET m.sal = ROUND(m.sal*1.1)
1.1을 곱하는 것 자체가 10%인상입니다. 만약 m.sal이 100이면, 1.1을 곱하면 110이되니 10% 인상)
마농님이 위에 답변을 보시면 update문 실행된 로우안에서 delete가 탄다고했으니 20부서를 지우니 10부서만 남았네요 부서 10번만 남았으니 조건에 만족합니다. 삭제전에 10번 20번부서를 모두 10%인상후 반올림했는데, 20부서를 지웠습니다.
ㄷ > 부서번호 30의 사원급여를 20% 인상인데 부서번호 30이라는조건이 어디에있는지..
ON 절에 m.empno=e.empno 만으로는 잘이해가안되네요 .. 도와주세요
-> emp테이블에 부서가 어디까지 있는지를 모르기때문에 정확하게 정의했으면 문제가 없었을 것 같습니다. (emp 테이블에 부서가 10~30까지밖에없다고하면 예제2 번 merge문은 문제가 없습니다.)
확실하게 하려면 insert 문에 예제 1번처럼 where 조건을 넣어야 합니다. ( where e.deptno ='30' )
예제2)
MERGE INTO emp_merge_test m
USING emp e
ON (m.empno = e.empno)
WHEN MATCHED THEN
UPDATE SET m.sal = ROUND(m.sal*1.1) -- 1.1 곱이 10% 인상
DELETE WHERE (m.deptno = 20) -- 부서번호 20의 사원정보는 삭제. -- 테이블에 부서가 10번,20번중에 20번을 지우니 부서번호 10번만 남음
WHEN NOT MATCHED THEN -- emp 테이블에 부서가 30까지라고하면 맞지만 40,50같은 부서가 존재하면 잘못된 merge문이 되버림, 확실하게 하려면 insert 문에 예제 1번처럼 where 조건을 넣으면 됨. ( where e.deptno ='30' )
INSERT (m.empno, m.deptno, m.sal)
VALUES (e.empno, e.deptno, ROUND(e.sal*1.2));