안녕하세요. 귀신이 곡할 노릇이 생겨 질문을 올립니다.
프로시저 구성은 아래와 같습니다.
--------------------------------------------
BEGIN
DECLARE @cnt int
DECLARE @tmpData TABLE
(
... 생략 ...
)
... 생략 ...
INSERT INTO @tmpData (
... 생략 ...
) SELECT
... 생략 ...
FROM A
INSERT INTO S (
... 생략 ...
) select
... 생략 ...
from @tmpData
SET @cnt = (SELECT COUNT(1) FROM @tmpData)
UPDATE B SET cnt = @cnt where ... 생략 ...
END
------------------------------------------------------------
설명을 드리면 @tmpData을 S 테이블과 동일한 형테로 구성을 한후 A테이블에서 데이타를 @tmpData로 insert 합니다.
그리고 @tmpData에서 S 테이블로 데이타를 그대로 옮깁니다.
그후 B 테이블에 cnt 값을 업데이트 합니다.
그런데 지금 결과가
B테이블에 cnt는 들어왔는데 정작 S 테이블에는 데이타가 없습니다.
건수는 약 50만건 정도 됩니다.
S테이블로 insert 할때 오류가 났으면 B테이블에 cnt도 안들어 갔어야 하는데 cnt에는 정상적인 값이 들어가 있습니다.
더 이상한건 다른 처리없이 프로시저를 다시 실행을 시켰더니 데이타가 정상적으로 S 테이블에 들어왔습니다.
이건 어떻게 이해를 해야 되는 건지 조언 부탁드립니다.
Comment 7
-
처리짱
2014.07.04 11:08
-
연금술사
2014.07.04 11:21
답변 감사합니다.
일반 테이블은 맞습니다.
하지만 삭제를 하는 구문은 따로 없고 계속 쌓아 두기만 합니다.
-
Hisory
2014.07.04 11:21
저 위에 begin tran 되어있고 아래에서 rollback 시키는 로직이 있지 않을까 하는 생각입니다.
-
연금술사
2014.07.04 11:23
답변 감사합니다.
트랜젝션을 거는 구문은 따로 없습니다.
-
항해자™
2014.07.04 23:23
오류가 발생한 것은 인덱스 제약조건 중 unique에 위배되는 경우의 수가 있어서 그렇습니다.
해당 구문은 오류가 발생해서 지나가지만 오류가 발생해도 다음 문장은 실행합니다.
프로시저 최 상단에 set xact_abort on 을 추가하시고, 가능하면 트랜젝션을 사용하시길 권장합니다.
그리고 맨 마지막에 SET @cnt = (SELECT COUNT(1) FROM @tmpData) 구문은,,
SET @cnt = @@ROWCOUNT 로 대체할 수 있겠네요,,,
-
연금술사
2014.07.07 10:04
감사글이 늦었습니다.
말씀하신 내용중에 두가지 질문이 있습니다.
1. "해당 구문은 오류가 발생해서 지나가지만 오류가 발생해도 다음 문장은 실행합니다."에서
"해당 구문"이 "insert S테이블 select 임시테이블" 구문을 말씀 하시는 건가요?
그럼 10번째 row를 insert할때 오류가 나면 이전에 9개째는 insert가 되어져 있는 건가요?
2. 그리고 "다음 문장"은 "SET @cnt=..." 구문을 말씀 하시는 거죠?
조언 부탁드립니다.
-
초탁
2014.07.09 16:36
http://technet.microsoft.com/ko-kr/library/ms188792(v=sql.90)
참고하시기 바랍니다.
간단히 에러구문만 롤백되느냐 전체가 롤백되느냐 입니다.
제 생각에는 S 이게 일반 테이블이라면
인서트 하기전에 S를 삭제하는 구문이 있을듯한데요..
거기서 지우는게 아닐듯 하네요