by 느훼훼 [Oracle 기초] [2019.01.25 11:18:03]
특정 테이블 여러개를 조인한 SELECT문의 결과 내역의 특정 컬럼을 특정 테이블 1개에 UPDATE
를 해야하는 쿼리를 짰는데요.
제가 알고 있기를 다중 테이블 조인을 건 쿼리의 결과물을 가지고 UPDATE 쿼리를 짤 때
bypass_ujvc 힌트를 달아야만 정상 실행이 되는줄 알고 있었거든요.
근데 오늘 해보니 힌트절을 안써도 에러 발생이 안되고 정상적으로 update 되더라구요.
이거 왜 그런걸까요? 혹시 오라클이 버전업 되어서 그런걸까요;;
update
(
select ~~~ from 테이블 a,
( select ~~~ from 테이블 a, 테이블 b, 테이블 c where 조인문)
) set 컬럼 = '기타'
이런 sql 문장이거든요.
키 보존과 관련된 문제입니다.
a : b 의 관계가 1 : 1 관계의 조인시에는
a, b 양쪽 테이블의 키가 모두 보존되어 양쪽 테이블 업데이트 가능합니다.
a : b 의 관계가 1 : m 관계의 조인시에는
m 쪽 집합만 키 보존되어 b 테이블만 업데이트 가능합니다.
1 쪽 집합은 m 배 만큼 늘어나므로 키보존 안됩니다.
키보존 가능 여부는 반대되는 1 쪽 집합에 PK 또는 UK 가 설정되었는지로 판단합니다.
즉, m:1 또는 1:1 조인시 1 쪽 집합에 pk 가 있으면 뷰에 대한 갱신이 가능합니다.
PK 가 없으면 키보존 오류가 나면서 갱신이 안되죠.
다만 PK 는 없지만 m:1 조인이 확실한 경우라면?
bypass_ujvc 힌트로 사용자가 직접 키보존에 대한 보증을 하는 것입니다.
오라클 옵티마이져는 사용자를 믿고 오류를 내지 않고 실행시켜 주는 건데요.
사용자를 믿었지만 거짓말 하는 사용자가 늘어나면서 해당 힌트를 없앤 듯 하네요.
11G 부터는 이 힌트가 인정되지 않습니다.
-- 예) 사원 : 부서 = M : 1 관계 UPDATE ( SELECT e.empno , e.ename , d.deptno , d.dname FROM emp e , dept d WHERE e.deptno = d.deptno ) SET ename = 'manon94' -- 갱신 가능 , dname = 'gurubee' -- 갱신 불가 WHERE empno = 9999 ; -- 부서의 d.deptno 가 PK 이므로 emp 테이블의 키 보존. emp 업데이트 가능
참고 : 조인 업데이트 구문
http://gurubee.net/article/79308