[ MSSQL + ibatis ] selectKey 사용시 @@IDENTITY 대신 SCOPE_IDENTITY() 를 사용
IT/db 2013. 3. 20. 17:06<요약>
[MSSQL + ibatis] insert 후 selectKey 사용시 @@IDENTITY 대신 SCOPE_IDENTITY() 를 사용해야한다.
<설명>
ibatis 한글매뉴얼 "iBATIS-SqlMaps-2_ko.pdf" 에 따르면
insert 후 자동생성키를 리턴받기위한 예제를 아래와 같이 기술하고 있다.
<!— Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
insert into PRODUCT (PRD_DESCRIPTION) values (#description#)
<selectKey resultClass="int" keyProperty="id" >
SELECT @@IDENTITY AS ID
</selectKey>
</insert>
그러나, 다른 값이 나오는 오류가 발견되었다.
이를 해결하는 방법은 다음과 같다.
@@IDENTITY 대신 SCOPE_IDENTITY() 를 사용해야한다.
<!— Microsoft SQL Server IDENTITY Column Example -->
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
<selectKey resultClass="int" keyProperty="id" >
insert into PRODUCT (PRD_DESCRIPTION) values (#description#)
SELECT SCOPE_IDENTITY() as ID
</selectKey>
</insert>
<오류현상>
@@IDENTITY 를 사용할 경우 실제 INSERTED 된 value 가 아니라 identity row num 나오는 현상이 발견.
<차이점> MSSQL @@IDENTITY , SCOPE_IDENTITY, IDENT_CURRENT 차이점 알기
@@IDENTITY
@@의 의미는 세션이다. 즉 해당 세션에서 테이블에 insert 된 최종값을 의미한다.
멀티스레팅에서 엉뚱한 값이 들어갈 확률이 높다.
IDENT_CURRENT('테이블명')
세션에 상관없이 해당 테이블에 대한 최종값 또는 들어갈 값을 의미한다.
다른 IDENTITY 와 다르게 데이터 입력전에 그 값을 알 수 있다.
하지만 테으블 전체에 대한 값을 의미하므로 1인용 시스템에나 적합하다.
SCOPE_IDENTITY()
마지막으로 해당 프로세스 + 해당 세션의 최종 IDENTITY 를 가져온다.
이 함수가 실행되는 곳이 SP 이거나 FN 이거나 TRIGGER 일 수도 있다. 그렇다면 해당 프로세스+세션으로 제한을 걸고 IDENTITY 를 가져오기 때문에 실시간 키코드를 리턴해야하는 상황에서 가장 신뢰할 수 있는 함수이다.
<정리>
다른 디비벤더과 함께 정리해보면
ORACLE 현재시퀀스 : NEWKEY.CURRVAL
ORACLE 다음시퀀스 : NEWKEY.NEXTVAL
MYSQL : LAST_INSERT_ID()
MSSQL : SCOPE_IDENTITY()
<참조>
http://mcpicdtl.blogspot.kr/2009/12/mssql-identity-scopeidentity.html
http://kaludin.egloos.com/2717396
'IT > db' 카테고리의 다른 글
MSSQL2008 에서 getdate 를 이용해서 rowindex 구하기 (0) | 2013.12.18 |
---|---|
DB_SQL_Convert_날짜등의변환 (0) | 2013.11.26 |
sybase NULL 취급 결함 (0) | 2011.09.29 |
Aqua Data Studio 4.7.2 재설치 후 연결정보 살리기 (0) | 2011.07.12 |
DB 서버 function ISNULL (0) | 2011.02.10 |