개발중에 다음의 쿼리를 돌릴때 에러가 발생합니다.
UPDATE /*+ bypass_ujvc +*/
(SELECT A.CLASS_NAME A_CLASS_NAME, B.CLASS_NAME B_CLASS_NAME FROM sso_user_incs A, sso_user B WHERE A.USER_ID = B.USER_ID AND B.CLASS_NAME <> ' ')
SET A_CLASS_NAME = B_CLASS_NAME
=== 에러 ====
ORA-01779: cannot modify a column which maps to a non key-preserved table
키 값이 중복이 날때 나는 에러라 하는데.. 무엇인지 찾아보아도 잘 모르겠네요..
SELECT A.CLASS_NAME A_CLASS_NAME, B.CLASS_NAME B_CLASS_NAME FROM sso_user_incs A, sso_user B WHERE A.USER_ID = B.USER_ID AND B.CLASS_NAME <> ' ' <==== 이렇게만 돌리면 결과값이 잘 나옵니다.
이런경우를 보신분은.. 답변 부탁드립니다.
한가지 궁금한 것이 있는데요..
sso_user 테이블은 view로 생성이 되어있어서 인덱스를 걸 수가 없습니다.
중복값이 걸리는지 확인할 결과 중복이 없구요..
===== 질문 =====
1. 비교하는 테이블이 view 테이블이면 위의 구문은 쓸수 없나요??
bypass_ujvc 힌트 없이 위 업데이트가 가능하려면
b.user_id 에 Unique Index 가 있어야만 합니다.
즉, 유니크인덱스가 a 와 b 의 관계가 1:1 또는 m:1 임을 보장해 주는 것입니다.
bypass_ujvc 힌트는 유니크인덱스가 없어도
명령어을 실행하는 사람이 이를 보장하겠다는 힌트입니다.
하지만 말로만 보장하고 실제로는 아닌 경우가 발생뒬 수 있으므로
bypass_ujvc 힌트는 비공식 힌트이며, 11g 부터는 아예 사용 불가합니다.
머지 구문을 이용하세요.
MERGE INTO a
USING b
ON (a.user_id = b.user_id)
WHEN MATCHED THEN
UPDATE SET class_name = b.class_name
;
-- 9i 라면??? -- WHEN NOT MATCHED THEN 구문도 필수입니다만... -- bypass_ujvc 힌트도 사용 가능 할 텐데요??? -- 일단 3가지 방법이 있습니다. -- 1. 전통적인 오라클 업데이트 UPDATE sso_user_incs a SET class_name = (SELECT class_name FROM sso_user WHERE user_id = a.user_id AND class_name != ' ') WHERE EXISTS (SELECT 1 FROM sso_user WHERE user_id = a.user_id AND class_name != ' ') ; -- 2. 머지 : Not Matched 상황이 발생하지 않도록 Using 절 조절 MERGE INTO sso_user_incs a USING ( SELECT b.user_id , b.class_name FROM sso_user_incs a , sso_user b WHERE a.user_id = b.user_id AND b.class_name != ' ' ) b ON (a.user_id = b.user_id) WHEN MATCHED THEN UPDATE SET class_name = b.class_name WHEN NOT MATCHED THEN INSERT(user_id, class_name) VALUES(b.user_id, b.class_name) ; -- 3. Bypass_ujvc 힌트 사용