1:N중 N인 디테일을 마스터와 조인해서 UPDATE하는데 에러가;; 0 6 3,366

by 조조맹덕 [2009.09.24 17:21:04]


n인 테이블에 update...

아... 오라클경험은 이제 2년인것도 있고.. 최근엔 db에 대해 고난이도 쿼리를 안해서..

개발 짬밥이 부끄럽게 해결책을 못찾겠군요.

SQL SERVER와.. 일괄 UPDATE는 많이 틀리네요 ㅠㅠ

현재 테이블 구조를 고치게 되면서.. 원래 1:n 인 마스터와 디테일 테이블에..

마스터 테이블 키가 바뀌어 디테일 테이블에 일단 컬럼 한개 추가해서

바뀐 키를 업데이트할려고 하는게 주 일입니다.

바꿀때 조건은 마스터테이블의 키를 가지고 하는거구요.

일단 아래와 같이 쿼리를 짰는데..

UPDATE detailTable A
SET A.newID = (SELECT B.newID FROM
masterTable B WHERE A.oldID= B.oldID
)

로 하니... 하위쿼리에서 2개의 이상의 행이 리턴되었다고 에러납니다.

음..그렇겠죠.. 마스터테이블에서 하위 테이블로 가는거니깐..

그래서 서브쿼리안에 DISTINCT 혹은 GROUP BY를 넣어도.. 마찬가지입니다.

이건 첨엔 이해가 안갔는데...  구조상 디테일테이블의 모든 행을 긁는 구조다

보니 서브쿼리에서 제가 그룹바이등을 넣어도.. 실제로 그렇게 동작은 안된게

아닐까.. 생각드는데요.

이 경우 어떻게 쿼리를 해야할지... 고수님들의 조언을 바랍니다 (__)

by 러드 [2009.09.24 17:33:12]
UPDATE detailTable A
SET A.newID = (SELECT B.newID FROM
masterTable B WHERE A.oldID= B.oldID
)
where exists (SELECT 1 FROM
masterTable B WHERE A.oldID= B.oldID
)

하던지

이것보다는 이렇게

UPDATE
(
SELECT B.newID , A.newID
FROM detailTable A,masterTable B
WHERE A.oldID= B.oldID
)
SET A.newID = B.newID

by 서성우 [2009.09.25 09:16:15]
primary key값을 확인해보세요

OLDID 만으로는 유니크한 값을 조회를 못하는것 같네요
(다수의 값 조회 , 1건만 조회 되어야 update 가능)

마스터 테이블과 디테일 테이블의

유니크한 값들을 찾아서

비교 해주셔야 에러가 나지 않습니다.

by 러드 [2009.09.25 10:02:51]
UPDATE (
SELECT A.newID AS NEW_ID_A
, B.newID AS NEW_ID_B
FROM detailTable A
, masterTable B
WHERE A.oldID= B.oldID
AND ROWNUM < 2
)
SET NEW_ID_A = NEW_ID_B

조인절이 맞다면 이렇게 하면 처리 됩니다.^^

2번째에 제가 B.newID , A.newID 했는데 잘못 적어 놨네요;;;;

by 조조맹덕 [2009.09.25 10:21:22]
친절히 답변 달아주셔서 매우 감사합니다. 러드님 ^^
답변 중 1번, 2번을 시도는 해봤는데.. 1번 경우 응답시간이너무 늦었구요.
다반 select 1 이 아니라 기존 set문과 동일한 쿼리 였었구요.
응답이 늦어서 lock걸려버리더라는;;
2번 경우엔 ORA-01732: 뷰에 대한 데이터 조작이 부적합합니다
란 메세지가 뜨더군요. 2번 경우엔 그 앞 masterTable에 새 값들을 붓는다고
2번과 같은 쿼리를 썼기에.. 문법상 실수가 있었던거 같진 않구요.

서성수님 리플처럼... 아마 유니크한 값이 아니여서 인거 같은데....
이게 구조상 디테일 테이블이 n건인 구조다 보니... 마스터테이블에선
분명 유니크한 값인데 디테일테이블에선 유니크할수 없는 구조라...
그래서 구조상
UPDATE detailTable A
SET A.newID = (SELECT B.newID FROM
masterTable B WHERE A.oldID= B.oldID
AND ROW NUM < 2
)
가 되어도 되는 쿼리인데.. 너무 느리더군요;; 200만건이라해도
2시간 넘게 응답이 없는건 좀 이상해서 캔슬했습니다..
여튼 답변 넘 감사드리고.. 이렇게 안되더라도,
작업용 임시테이블을 만들고, 구조는 디테일테이블ID, OLDID, NEWID가진 넘으루..
INSERT.. SELECT루..
그렇게 행수가 DETAILTABLE과 똑같은 넘으루 만들어서..
1:1로 업데이트 할려고 합니다. 좀 노가다지만.. INSERT SELECT가 원체 빨리
동작하고, 그 테이블 가지고 1:1로 UPDATE하면..
안전하기도 하고 시간이 별로 안걸릴거 같아서요;;

혹 다른 좋은 의견 있으시면 달아주셔도 감사하겠습니다 ^^

by 조조맹덕 [2009.09.25 10:40:39]
음.. 전체 UPDATE를
WHERE ROWNUM < 50000
AND 타겟테이블.NEWID IS NULL
로 5만건씩 끊어서 하고 있습니다 -_-;
이렇게하니 그나마 몇십초만에 떨어지네요;;

by 최단경로 [2009.09.25 13:05:52]
음. 러드님이나 서성우님이 말씀하신 방법도 있고. 또 질문자님께서 5만건씩 잘라서 처리 하신 방법도 있지만.
Merge Into를 응용하여 사용하는 방법도 있습니다. ^^
Merge Into를 사용했을때 원하시는 응답속도가 나올지는 모르겠네요.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입