메뉴 건너뛰기

bysql.net


-- 호기심 : 과연 MERGE 문에서 DELETE CLAUSE 에서도 참조열을 가져다 써도 무방할것인가?

-- 1. 사원테이블을 하나 복제를 한다.
CREATE TABLE DARKBEOM_EMP
AS SELECT * FROM EMP;

-- 2. 복제테이블의 DATA 모두 SAL + 1000 해준다.
UPDATE DARKBEOM_EMP
SET  SAL = SAL + 1000

COMMIT;

-- RESULT
Row#    EMPNO    ENAME    JOB   SAL

1    7369    SMITH    CLERK     1800
2    7499    ALLEN    SALESMAN  2600
3    7521    WARD     SALESMAN  2250
4    7566    JONES    MANAGER   3975
5    7654    MARTIN   SALESMAN  2250
6    7698    BLAKE    MANAGER   3850
7    7782    CLARK    MANAGER   3450
8    7788    SCOTT    ANALYST   4000
9    7839    KING     PRESIDENT 6000
10   7844    TURNER   SALESMAN  2500
11   7876    ADAMS    CLERK     2100
12   7900    JAMES    CLERK     1950
13   7902    FORD     ANALYST   4000
14   7934    MILLER   CLERK     2300

-- EMP 에서 SAL 값이 '800' 인 값 확인
SELECT * FROM EMP S WHERE S.SAL = '800'

-- RESULT
Row#    EMPNO    ENAME    JOB     SAL
1       7369     SMITH    CLERK   800

-- 3. 원본 테이블의 SAL 값이 '800' 인 값만 삭제해보기
MERGE INTO DARKBEOM_EMP T USING EMP S ON (T.EMPNO = S.EMPNO)
WHEN MATCHED THEN
     UPDATE
            SET T.SAL = S.SAL
     DELETE WHERE S.SAL > 1000
WHEN NOT MATCHED THEN INSERT
(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES
(S.EMPNO, S.ENAME, S.JOB, S.MGR, S.HIREDATE, S.SAL, S.COMM, S.DEPTNO);


SELECT 'DARKBEOM_EMP' AS TAB, COUNT(*) FROM DARKBEOM_EMP S
UNION ALL
SELECT 'EMP' AS TAB, COUNT(*) FROM EMP S

-- RESULT
1    DARKBEOM_EMP    13
2    EMP             14

SELECT * FROM DARKBEOM_EMP S WHERE S.ENAME = 'SMITH'
-- SMITH가 사라졌다.

-- 4. 원본 테이블의 SAL 값이 '1000' 보다 큰값만 삭제해보기
MERGE INTO DARKBEOM_EMP T USING EMP S ON (T.EMPNO = S.EMPNO)
WHEN MATCHED THEN
     UPDATE
            SET T.EMPNO = S.EMPNO
     DELETE WHERE T.EMPNO = S.EMPNO AND S.SAL > 1000
WHEN NOT MATCHED THEN INSERT
(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES
(S.EMPNO, S.ENAME, S.JOB, S.MGR, S.HIREDATE, S.SAL, S.COMM, S.DEPTNO);


SELECT 'DARKBEOM_EMP' AS TAB, COUNT(*) FROM DARKBEOM_EMP S
UNION ALL
SELECT 'EMP' AS TAB, COUNT(*) FROM EMP S

-- RESULT
1    DARKBEOM_EMP    2
2    EMP             14


/*
5. 결과 : MERGE 문 사용시 ON (T.EMPNO = S.EMPNO) 절에 사용된 열이 UPDATE 문에 사용했을시에는
          ORA-38104: ON 절에서 참조되는 열은 갱신할 수 없음: "T"."EMPNO" 참조열에 대한 갱신은 이뤄질수없다.
          하지만, 삭제 구문에서 ON 절에 쓰인 해당 참조열은 써도 무방하다! 
          자체 결론... 갱신 대상은 될 수 없지만 삭제 대상은 된다. (시간관계상 더 깊은 원리는 SKIP..)
*/


예외 : 테스트 해본 결과 DBLINK 시 DELETE 문은 ERROR를 발생시키네요.. 이유는 모르겠어요..


사실 MERGE 문에 대한 전반적인 메커니즘은 이해하지 못했습니다.

혹시 부족한점이나 부가적으로 설명 달아주시면 감사해요~ (__)