일반적으로 고객사 인사DB에서 DTS로 긁어와서 우리 쪽의 인사정보 테이블에 동기화시키는 작업을 새벽에 예약 수행하게 된다. 이런 작업은 보통 다음과 같은 두 단계로 이루어진다.
- DTS로 고객사 인사DB 내용을 우리쪽에 긁어와서 TEMP TABLE에 저장한다.
- TEMP TABLE과 실제 우리측 인사정보 테이블과 비교하여 변경된 사항을 UPDATE 혹은 INSERT한다.
문제는 고객사 DB의 정보가 잘못된 경우이다. 이럴 땐 데이터가 잘못된 한개의 레코드때문에 전체 데이터의 업데이트가 ROLLBACK되어 버린다. 더욱 큰 문제는, 도대체 어느 레코드가 문제인지 찾기가 쉽지 않다는 것이다. 그래서 TEMP TABLE에 긁어온 데이터를 인사정보 TABLE에 반영할 때는 다음과 같이 해야 한다.
- DTS로 고객사 인사DB 내용을 우리쪽에 긁어와서 TEMP TABLE에 저장한다.
- TEMP TABLE에서 레코드 1개씩 읽어들여서 기존의 인사정보 TABLE과 비교, 없다면 INSERT하고, 변경되었다면 UPDATE, 변경사항 없다면 SKIP한다. 이때 만약 UPDATE 및 INSERT에 오류가 발생한다면 내용을 이벤트로그 등에 기록한다.
- 2번을 모든 TEMP TABLE 레코드에 대해 반복하며 수행한다.
실제 SQL 프로시져로 쓰면 다음과 같이 된다.
DECLARE @USER_SABUN VARCHAR(20), @USER_NAME VARCHAR(20), @USER_DEPT_CODE VARCHAR(20), @USER_STATUS INT, @ErrorMsg VARCHAR(200) DECLARE Cur CURSOR FOR SELECT USER_SABUN, USER_NAME, USER_DEPT_CODE, USER_STATUS FROM INSA_INFO_TEMP OPEN Cur FETCH NEXT FROM Cur INTO @USER_SABUN, @USER_NAME, @USER_DEPT_CODE, @USER_STATUS WHILE (@@FETCH_STATUS = 0) BEGIN IF (NOT EXISTS (SELECT * FROM INSA_INFO WHERE USER_SABUN = @USER_SABUN)) BEGIN INSERT INTO INSA_INFO (USER_SABUN, USER_NAME, USER_DEPT_CODE, USER_STATUS) VALUES (@USER_SABUN, @USER_NAME, @USER_DEPT_CODE, @USER_STATUS) IF (@@ERROR > 0) BEGIN SET @ErrorMsg = '[인사정보 INSERT오류] 사번 : ' + @USER_SABUN + ' 에서 오류 발생. 오류코드 : ' + CONVERT(VARCHAR, @@ERROR) EXEC master..xp_logevent 50001, @ErrorMsg, WARNING CONTINUE END END ELSE BEGIN UPDATE INSA_INFO SET USER_NAME = @USER_NAME, USER_DEPT_CODE = @USER_DEPT_CODE, USER_STATUS = @USER_STATUS WHERE USER_SABUN = @USER_SABUN AND (SER_NAME != @USER_NAME OR USER_DEPT_CODE != @USER_DEPT_CODE OR USER_STATUS != @USER_STATUS) IF (@@ERROR > 0) BEGIN SET @ErrorMsg = '[인사정보 INSERT오류] 사번 : ' + @USER_SABUN + ' 에서 오류 발생. 오류코드 : ' + CONVERT(VARCHAR, @@ERROR) EXEC master..xp_logevent 50001, @ErrorMsg, WARNING CONTINUE END END FETCH NEXT FROM Cur INTO @USER_SABUN, @USER_NAME, @USER_DEPT_CODE, @USER_STATUS END CLOSE CUR DEALLOCATE CUR
'SQL Server' 카테고리의 다른 글
악성 쿼리 찾아내기(1) - ReadTrace (1) | 2008.12.22 |
---|---|
"NOT IN" SUBQUERY 대체하기 (0) | 2008.08.27 |
테이블에 블로킹이 풀리지 않을 때의 응급조치방법 (0) | 2008.08.24 |
대용량 로그테이블 삭제하기 (DELETE 문에 TOP 구현하기) (2) | 2008.08.23 |
여러개의 테이블에서 JOIN하여 UPDATE 및 DELETE하는 SQL (5) | 2008.08.21 |