안녕하세요.
update를 하는데 효과적인 방법이 안떠올라 문의 드립니다.
CREATE TABLE ZIP(
ZIP1 VARCHAR2(10)
,ZIP2 VARCHAR2(10)
,ZIP3 VARCHAR2(10)
,ZIP4 VARCHAR2(10)
,ZIP5 VARCHAR2(10)
);
CREATE TABLE MODIFY_ZIP(
OLD_ZIP VARCHAR2(10)
,NEW_ZIP VARCHAR2(10)
);
INSERT INTO ZIP VALUES( 'A' , 'S' , NULL , 'F' , 'X');
INSERT INTO ZIP VALUES( 'M' , 'D' , 'DD' , 'MM' , 'M');
INSERT INTO ZIP VALUES( NULL , 'C' , 'C' , NULL , 'C');
INSERT INTO ZIP VALUES( 'S' , 'C' , 'SS' , 'F' , 'X');
INSERT INTO ZIP VALUES( 'C' , 'S' , 'GG' , 'F' , 'G');
INSERT INTO MODIFY_ZIP VALUES( 'C' , 'CC');
INSERT INTO MODIFY_ZIP VALUES( 'S' , 'SS');
INSERT INTO MODIFY_ZIP VALUES( 'G' , 'GG');
zip 테이블에 있는 값들 중 modify_zip의 OLD_ZIP에 해당 값이 있으면 NEW_ZIP 값으로 바꿔야하는 문제 입니다.
한꺼번에 바꿀수 있는 방법이 안떠오르네요....
UPDATE
A
SET
ZIP1 = (CASE ZIP1 WHEN B.OLD_ZIP THEN B.NEW_ZIP ELSE ZIP1 END)
,ZIP2 = (CASE ZIP2 WHEN C.OLD_ZIP THEN C.NEW_ZIP ELSE ZIP2 END)
,ZIP3 = (CASE ZIP3 WHEN D.OLD_ZIP THEN D.NEW_ZIP ELSE ZIP3 END)
,ZIP4 = (CASE ZIP4 WHEN E.OLD_ZIP THEN E.NEW_ZIP ELSE ZIP4 END)
,ZIP5 = (CASE ZIP5 WHEN F.OLD_ZIP THEN F.NEW_ZIP ELSE ZIP5 END)
FROM
ZIP AS A
INNER JOIN MODIFY_ZIP AS B ON A.ZIP1 = B.OLD_ZIP
INNER JOIN MODIFY_ZIP AS C ON A.ZIP2 = C.OLD_ZIP
INNER JOIN MODIFY_ZIP AS D ON A.ZIP3 = D.OLD_ZIP
INNER JOIN MODIFY_ZIP AS E ON A.ZIP4 = E.OLD_ZIP
INNER JOIN MODIFY_ZIP AS F ON A.ZIP5 = F.OLD_ZIP;
이렇게 하면 될까 했는데...안되는군요...update에서는 with 도 안되고...
좋은 방법 있으시면 지도 부탁드립니다 ^^
오라클 업데이트 구문에는 조인 구문이 없습니다.
따라서 서브쿼리 형태로 조건을 주어야 하고, 성능에도 상당히 안좋습니다.
위 예제처럼 데이터가 몇건 안된다면 큰 문제 없지만.
데이터가 많은데 위처럼 인덱스도 없는 상황에서는 상당히 위험합니다.
인덱스 설정이 반드시 필요하구요.
머지 구문을 이용하는것도 한 방법입니다.
UPDATE zip a SET zip1 = (SELECT NVL(MIN(new_zip), a.zip1) FROM modify_zip b WHERE b.old_zip = a.zip1) , zip2 = (SELECT NVL(MIN(new_zip), a.zip2) FROM modify_zip b WHERE b.old_zip = a.zip2) , zip3 = (SELECT NVL(MIN(new_zip), a.zip3) FROM modify_zip b WHERE b.old_zip = a.zip3) , zip4 = (SELECT NVL(MIN(new_zip), a.zip4) FROM modify_zip b WHERE b.old_zip = a.zip4) , zip5 = (SELECT NVL(MIN(new_zip), a.zip5) FROM modify_zip b WHERE b.old_zip = a.zip5) WHERE EXISTS (SELECT 1 FROM modify_zip b WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5) ) ;
UPDATE zip a SET (zip1, zip2, zip3, zip4, zip5) = (SELECT MIN(DECODE(a.zip1, b.old_zip, b.new_zip, a.zip1)) zip1 , MIN(DECODE(a.zip2, b.old_zip, b.new_zip, a.zip2)) zip2 , MIN(DECODE(a.zip3, b.old_zip, b.new_zip, a.zip3)) zip3 , MIN(DECODE(a.zip4, b.old_zip, b.new_zip, a.zip4)) zip4 , MIN(DECODE(a.zip5, b.old_zip, b.new_zip, a.zip5)) zip5 FROM modify_zip b WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5) ) WHERE EXISTS (SELECT 1 FROM modify_zip b WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5) ) ;
MERGE INTO zip a USING ( SELECT a.ROWID rid , MIN(DECODE(a.zip1, b.old_zip, b.new_zip, a.zip1)) zip1 , MIN(DECODE(a.zip2, b.old_zip, b.new_zip, a.zip2)) zip2 , MIN(DECODE(a.zip3, b.old_zip, b.new_zip, a.zip3)) zip3 , MIN(DECODE(a.zip4, b.old_zip, b.new_zip, a.zip4)) zip4 , MIN(DECODE(a.zip5, b.old_zip, b.new_zip, a.zip5)) zip5 FROM zip a , modify_zip b WHERE b.old_zip IN (a.zip1, a.zip2, a.zip3, a.zip4, a.zip5) GROUP BY a.ROWID ) b ON (a.ROWID = b.rid) WHEN MATCHED THEN UPDATE SET a.zip1 = b.zip1 , a.zip2 = b.zip2 , a.zip3 = b.zip3 , a.zip4 = b.zip4 , a.zip5 = b.zip5 ;