다음을 통해 공유


SCOPE_IDENTITY(Transact-SQL)

적용 대상: SQL Server Azure SQL 데이터베이스 Azure SQL Managed Instance

같은 범위에서 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 값은 계속 증가합니다.

예제

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

다음 예에서는 두 개의 테이블 TZTY를 만들고 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'),('Mike'),('Carla');  
  
SELECT * FROM TZ;  

결과 집합: 테이블 TZ를 보여주는 방법입니다.

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'), ('rocks'), ('elevator');  
  
SELECT * FROM TY;  

결과 집합: TY를 보여주는 방법입니다.

Y_id  Y_name  
---------------  
100   boathouse  
105   rocks  
110   elevator  

행이 테이블 TZ에 삽입될 때 행을 테이블 TY에 행을 삽입하는 트리거를 작성합니다.

CREATE TRIGGER Ztrig  
ON TZ  
FOR INSERT AS   
   BEGIN  
   INSERT TY VALUES ('')  
   END;  

트리거를 시작하고 @@IDENTITY 및 SCOPE_IDENTITY 함수로 사용자가 어떤 ID 값을 얻게 할지 결정합니다.

INSERT TZ VALUES ('Rosalie');  
  
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  
GO  
SELECT @@IDENTITY AS [@@IDENTITY];  
GO  

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

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

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

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

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

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

USE AdventureWorks2022;  
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입니다. 테이블에 행을 삽입하면 @@IDENTITYSCOPE_IDENTITY()에서 서로 다른 값을 반환합니다. SCOPE_IDENTITY()는 사용자 테이블에 대한 삽입에서 값을 반환하는 반면 @@IDENTITY는 복제 시스템 테이블에 대한 삽입에서 값을 반환합니다. 삽입된 ID 값에 액세스해야 하는 애플리케이션에 대해 SCOPE_IDENTITY()를 사용합니다.

INSERT INTO Sales.Customer ([TerritoryID],[PersonID]) VALUES (8,NULL);  
GO  
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];  
GO  
SELECT @@IDENTITY AS [@@IDENTITY];  
GO  

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

SCOPE_IDENTITY  
29484  
@@IDENTITY  
89

참고 항목

@@IDENTITY(Transact-SQL)