반응형
일반적으로 고객사 인사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
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
반응형
'연구개발 > SQL2005' 카테고리의 다른 글
악성 쿼리 찾아내기(1) - ReadTrace (0) | 2009.06.27 |
---|---|
"NOT IN" SUBQUERY 대체하기 (0) | 2009.06.27 |
테이블에 블로킹이 풀리지 않을 때의 응급조치방법 (0) | 2009.06.27 |
INSTEAD OF 트리거 (0) | 2009.06.27 |
SELECT에 LOCK을 거는 방법 (0) | 2009.06.27 |