SCOPE_IDENTITY(Transact-SQL)

같은 범위에서 ID 열에 삽입된 마지막 ID 값을 반환합니다. 범위는 저장 프로시저, 트리거, 함수 또는 일괄 처리와 같은 모듈입니다. 따라서 두 문이 같은 저장 프로시저, 함수 또는 일괄 처리에 있으면 같은 범위에 있는 것입니다.

항목 링크 아이콘Transact-SQL 구문 표기 규칙

구문

SCOPE_IDENTITY()

반환 형식

numeric(38,0)

주의

SCOPE_IDENTITY, IDENT_CURRENT 및 @@IDENTITY는 ID 열에 삽입된 값을 반환하기 때문에 비슷한 함수입니다.

IDENT_CURRENT는 범위와 세션으로 제한되는 것이 아니라 지정된 테이블로 제한됩니다. IDENT_CURRENT는 임의 세션 및 범위에 있는 특정 테이블에 생성된 값을 반환합니다. 자세한 내용은 IDENT_CURRENT(Transact-SQL)를 참조하십시오.

SCOPE_IDENTITY 및 @@IDENTITY는 현재 세션의 테이블에서 생성된 마지막 ID 값을 반환합니다. 그러나 SCOPE_IDENTITY는 현재 범위 내에 삽입된 값을 반환합니다. @@IDENTITY는 특정 범위로 제한되지 않습니다.

예를 들어 두 개의 테이블 T1과 T2가 있고 T1에 INSERT 트리거가 정의되어 있다고 가정합니다. T1에 행이 삽입될 때 트리거가 발생하고 T2에서 행을 삽입합니다. 이 시나리오에서는 T1에서의 삽입과 트리거에 의한 T2에서의 삽입이라는 두 범위를 보여 줍니다.

T1과 T2에 모두 ID 열이 있고 @@IDENTITY 및 SCOPE_IDENTITY가 T1에서 INSERT 문 끝에 다른 값을 반환한다고 가정해 봅시다. @@IDENTITY는 현재 세션의 범위에서 삽입된 마지막 ID 열 값을 반환합니다. 이 값은 T2에 삽입된 값입니다. SCOPE_IDENTITY()는 T1에 삽입된 IDENTITY 값을 반환합니다. 이 값은 같은 범위에서 발생한 마지막 삽입 값입니다. 범위에서 ID 열에 INSERT 문이 발생하기 전에 SCOPE_IDENTITY() 함수가 호출되면 이 함수는 Null 값을 반환합니다.

문 및 트랜잭션이 실패해도 테이블의 현재 ID가 변경되고 ID 열 값 간에 간격이 생성될 수 있습니다. 테이블에 값을 삽입하려고 시도한 트랜잭션이 커밋되지 않아도 ID 값은 롤백되지 않습니다. 예를 들어 IGNORE_DUP_KEY 위반으로 인해 INSERT 문이 실패해도 테이블의 현재 ID 값은 계속 증가합니다.

1. 트리거에 @@IDENTITY 및 SCOPE_IDENTITY 사용

다음 예에서는 두 개의 테이블 TZ 및 TY를 만들고 TZ에서 INSERT 트리거를 만듭니다. TZ 테이블에 행이 삽입될 때 트리거(Ztrig)가 발생하고 TY에서 행을 삽입합니다.

USE tempdb
GO
CREATE TABLE TZ (
   Z_id  int IDENTITY(1,1)PRIMARY KEY,
   Z_name varchar(20) NOT NULL)

INSERT TZ
   VALUES ('Lisa')
INSERT TZ
   VALUES ('Mike')
INSERT TZ
   VALUES ('Carla')

SELECT * FROM TZ

--Result set: This is how table TZ looks.
Z_id   Z_name
-------------
1      Lisa
2      Mike
3      Carla

CREATE TABLE TY (
   Y_id  int IDENTITY(100,5)PRIMARY KEY,
   Y_name varchar(20) NULL)

INSERT TY (Y_name)
   VALUES ('boathouse')
INSERT TY (Y_name)
   VALUES ('rocks')
INSERT TY (Y_name)
   VALUES ('elevator')

SELECT * FROM TY
--Result set: This is how TY looks:
Y_id  Y_name
---------------
100   boathouse
105   rocks
110   elevator

/*Create the trigger that inserts a row in table TY 
when a row is inserted in table TZ*/
CREATE TRIGGER Ztrig
ON TZ
FOR INSERT AS 
   BEGIN
   INSERT TY VALUES ('')
   END

/*FIRE the trigger and determine what identity values you obtain 
with the @@IDENTITY and SCOPE_IDENTITY functions.*/
INSERT TZ VALUES ('Rosalie')

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO

결과 집합은 다음과 같습니다.

SCOPE_IDENTITY
4
/*SCOPE_IDENTITY returned the last identity value in the same scope. This was the insert on table TZ.*/

@@IDENTITY
115
/*@@IDENTITY returned the last identity value inserted to TY by the trigger. This fired because of an earlier insert on TZ.*/

2. 복제에 @@IDENTITY 및 SCOPE_IDENTITY() 사용

다음 예에서는 병합 복제용으로 게시된 데이터베이스에서 삽입을 위해 @@IDENTITY 및 SCOPE_IDENTITY()를 사용하는 방법을 보여 줍니다. 이 예의 두 테이블은 모두 AdventureWorks 예제 데이터베이스에 있습니다. Person.ContactType은 게시되지 않았고 Sales.Customer는 게시되었습니다. 병합 복제는 게시된 테이블에 트리거를 추가합니다. 따라서 @@IDENTITY는 사용자 테이블에 대한 삽입 대신 복제 시스템 테이블에 대한 삽입에서 값을 반환할 수 있습니다.

Person.ContactType 테이블의 최대 ID 값은 20입니다. 테이블에 행을 삽입하면 @@IDENTITY 및 SCOPE_IDENTITY()에서 동일한 값을 반환합니다.

USE AdventureWorks;
GO
INSERT INTO Person.ContactType ([Name]) VALUES ('Assistant to the Manager')
GO
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO

결과 집합은 다음과 같습니다.

SCOPE_IDENTITY
21

@@IDENTITY
21

Sales.Customer 테이블의 최대 ID 값은 29483입니다. 테이블에 행을 삽입하면 @@IDENTITY 및 SCOPE_IDENTITY()에서 서로 다른 값을 반환합니다. SCOPE_IDENTITY()는 사용자 테이블에 대한 삽입에서 값을 반환하는 반면 @@IDENTITY는 복제 시스템 테이블에 대한 삽입에서 값을 반환합니다. 삽입된 ID 값에 액세스해야 하는 응용 프로그램에 대해 SCOPE_IDENTITY()를 사용합니다.

INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (8,'S')
GO
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO

결과 집합은 다음과 같습니다.

SCOPE_IDENTITY
29484

@@IDENTITY
89

참고 항목

참조