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 : http://www.gurubee.net/lecture/2225
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.
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) where m.dept = 10
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
;
안녕하세요 초보자입니다..
예제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));