그동안 두개의 테이블을 조인해서 UPDATE 할때 너무나 원시적인 방법을 사용했었다.
BEGIN
FOR xx IN (SELECT A, B, C, D FROM TAB_A) LOOP
UPDATE TAB_B
SET A = xx.A
, D = xx.D
WHERE B = xx.B
AND C = xx.C;
END LOOP;
END;
COMMIT;
FOR xx IN (SELECT A, B, C, D FROM TAB_A) LOOP
UPDATE TAB_B
SET A = xx.A
, D = xx.D
WHERE B = xx.B
AND C = xx.C;
END LOOP;
END;
COMMIT;
TAB_B가 작은 테이블일 경우는 그닥 문제가 없지만, 조금 큰 테이블인경우는.. 답이 없다..
오늘 ORACLE의 좋은기능을 하나 발견했다.
UPDATE (
SELECT xx.A xx_A, xx.D xx_D, yy.A yy_A, yy.D yy_D
FROM TAB_A xx, TAB_B yy
WHERE xx.B = yy.B
AND xx.C = yy.C
)
SET yy_A = xx_A
, yy_D = xx_D;
COMMIT;
SELECT xx.A xx_A, xx.D xx_D, yy.A yy_A, yy.D yy_D
FROM TAB_A xx, TAB_B yy
WHERE xx.B = yy.B
AND xx.C = yy.C
)
SET yy_A = xx_A
, yy_D = xx_D;
COMMIT;
이렇게 쓸경우 oracle에서 다음과 같은 오류가 나오는 경우가 있다.
ORA-01779: cannot modify a column which maps to a non key-preserved table
그럴경우에는 다음과 같은 힌트를 사용하면 된다.
UPDATE /*+ bypass_ujvc */
(
SELECT xx.A xx_A, xx.D xx_D, yy.A yy_A, yy.D yy_D
FROM TAB_A xx, TAB_B yy
WHERE xx.B = yy.B
AND xx.C = yy.C
)
SET yy_A = xx_A
, yy_D = xx_D;
COMMIT;
(
SELECT xx.A xx_A, xx.D xx_D, yy.A yy_A, yy.D yy_D
FROM TAB_A xx, TAB_B yy
WHERE xx.B = yy.B
AND xx.C = yy.C
)
SET yy_A = xx_A
, yy_D = xx_D;
COMMIT;