데이터베이스/Mssql

SCOPE_IDENTITY() 함수란? – SQL Server에서 마지막으로 삽입된 ID값 안전하게 가져오기

Jinwookoh 2025. 5. 16. 23:40

 

 

데이터베이스에 새로운 레코드를 삽입한 직후, 그 레코드의 ID 값을 가져오는 일은 흔하면서도 중요한 작업입니다. 특히 외래 키로 연결된 다른 테이블에 데이터를 추가하거나 삽입된 ID 값을 기준으로 후속 로직을 처리할 때 반드시 필요하죠. SQL Server에서는 이를 위해 여러 함수를 제공하는데, 그중 가장 안전하고 권장되는 방법이 바로 SCOPE_IDENTITY()입니다.


✅ SCOPE_IDENTITY()란?

SCOPE_IDENTITY()는 현재 세션과 현재 스코프(scope) 내에서 마지막으로 생성된 IDENTITY 열의 값을 반환합니다.

즉, 어떤 프로시저나 배치 내에서 INSERT 문을 실행한 직후, 그로 인해 생성된 ID 값을 정확하게 얻을 수 있습니다. 트리거나 다른 병렬 프로세스에서 발생한 ID 값과 혼동될 일이 없습니다.

SELECT SCOPE_IDENTITY();

별도의 인수 없이 호출하며, 가장 최근 삽입된 IDENTITY 값을 반환합니다.


🔍 사용 예제

INSERT INTO Users (UserName, Email)
VALUES ('홍길동', 'hong@example.com');

SELECT SCOPE_IDENTITY() AS NewUserId;

또는 다음과 같이 변수로 받을 수 있습니다.

DECLARE @NewUserId INT;

INSERT INTO Users (UserName, Email)
VALUES ('홍길동', 'hong@example.com');

SET @NewUserId = SCOPE_IDENTITY();

INSERT INTO UserProfiles (UserId, ProfileImageUrl)
VALUES (@NewUserId, 'default.png');

위 예제처럼, 삽입된 사용자 ID를 받아서 UserProfiles 같은 관련 테이블에 함께 저장할 수 있습니다.


⚖️ 다른 ID 반환 함수들과의 비교

함수명 설명 주의사항

@@IDENTITY 현재 세션에서 가장 마지막으로 생성된 IDENTITY 값을 반환 트리거에서 생성된 값도 포함될 수 있어 위험
IDENT_CURRENT('테이블명') 특정 테이블에서 마지막으로 생성된 ID 값을 반환 스코프, 세션과 관계없이 반환됨. 병렬 실행 시 충돌 가능
SCOPE_IDENTITY() 같은 스코프, 같은 세션에서 생성된 ID 값을 반환 가장 안전하고 권장되는 방식 ✅

🧠 왜 SCOPE_IDENTITY()를 써야 할까?

1. 트리거에 의한 오작동 방지

@@IDENTITY는 트리거 안에서 생성된 ID 값도 포함할 수 있습니다. 이는 예기치 않은 결과를 유발할 수 있습니다. 반면 SCOPE_IDENTITY()는 현재 실행 중인 스코프만 기준으로 하기 때문에 안전합니다.

2. 병렬 트랜잭션에도 강함

다중 사용자가 동시에 INSERT를 수행하는 경우에도, SCOPE_IDENTITY()는 자신의 세션 + 스코프만 고려하므로 올바른 ID 값을 반환합니다.


📝 유의사항

  • IDENTITY 속성이 없는 테이블에서는 사용할 수 없습니다.
  • SCOPE_IDENTITY()는 반드시 INSERT 직후에 호출해야 의미가 있습니다.
  • 반복적으로 호출하는 대신 한 번 호출 후 변수에 저장해 사용하는 것이 좋습니다.

📌 요약

항목 내용

함수명 SCOPE_IDENTITY()
반환 값 현재 스코프 내에서 마지막으로 생성된 IDENTITY 값
사용 시기 INSERT 직후
안전성 트리거, 병렬 트랜잭션에서 발생할 수 있는 충돌을 방지
대체 함수 @@IDENTITY, IDENT_CURRENT (권장하지 않음)

결론

SCOPE_IDENTITY()는 SQL Server에서 레코드 삽입 후 ID 값을 정확하고 안전하게 가져오는 가장 좋은 방법입니다. 단순한 쿼리에서도, 복잡한 트랜잭션 로직에서도 신뢰할 수 있는 결과를 보장합니다. @@IDENTITY나 IDENT_CURRENT와 같은 유사 함수들도 있지만, 트리거나 병렬성 이슈를 고려하면 SCOPE_IDENTITY()가 훨씬 더 안전한 선택입니다.

개발자라면 삽입 ID 처리 시 항상 SCOPE_IDENTITY()를 기본값으로 생각하는 습관을 들여보세요.