SR0008: 대신 IDENTITY SCOPE_IDENTITY를 사용하십시오.

규칙 ID

SR0008

범주

Microsoft.Design

변경 수준

주요 변경 아님

원인

코드에 @@IDENTITY 호출이 있습니다.

규칙 설명

@@IDENTITY는 전역 ID 값이므로 현재 범위 외부에서 업데이트되었거나 예기치 않은 값을 얻었을 수 있습니다. 복제에 사용되는 중첩 트리거를 비롯한 트리거는 현재 범위 외부에서 @@IDENTITY를 업데이트할 수 있습니다.

위반 문제를 해결하는 방법

이 문제를 해결하려면 @@IDENTITY에 대한 참조를 SCOPE_IDENTITY로 바꿔야 합니다. 그러면 사용자 문의 범위에서 가장 최신 ID 값이 반환됩니다.

경고를 표시하지 않는 경우

@@IDENTITY를 사용하는 문이 사용된 경우 다른 처리를 통해 @@IDENTITY 값이 업데이트되지 않은 것이 확실하면 이 경고를 표시하지 않을 수 있습니다. 그러나 SCOPE_IDENTITY는 값이 예기치 않게 변경될 위험 없이 의도한 값을 제공하므로 경고를 표시하지 않는 것보다는 경고를 해결하는 것이 좋습니다.

예제

첫 번째 예제에서 IDENTITY는 테이블에 데이터를 삽입하는 저장 프로시저에 사용됩니다. 그런 다음 병합 복제를 위해 테이블이 게시되고 게시된 테이블에 트리거가 추가됩니다. 따라서 IDENTITY는 삽입 작업에서 사용자 테이블로 값을 반환하는 대신 삽입 작업에서 복제 시스템 테이블로 값을 반환할 수 있습니다.

Sales.Customer 테이블에 최대 ID 값 29483이 있습니다. 행을 테이블에 삽입하면 IDENTITY 및 SCOPE_IDENTITY()가 서로 다른 값을 반환합니다. SCOPE_IDENTITY()는 삽입 작업에서 사용자 테이블로 값을 반환하지만 IDENTITY는 삽입 작업에서 복제 시스템 테이블로 값을 반환합니다.

두 번째 예제에서는 SCOPE_IDENTITY()를 사용하여 삽입된 ID 값에 액세스하고 경고를 해결하는 방법을 보여 줍니다.

CREATE PROCEDURE [dbo].[ProcedureWithWarning]
@param1 INT, 
@param2 NCHAR(1),
@Param3 INT OUTPUT
AS
BEGIN
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (@param1,@param2);

SELECT @Param3 = @@IDENTITY
END

CREATE PROCEDURE [dbo].[ProcedureFixed]
@param1 INT, 
@param2 NCHAR(1),
@param3 INT OUTPUT
AS
BEGIN
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (@param1,@param2);

SELECT @Param3 = SCOPE_IDENTITY()
END

참고 항목

개념

데이터베이스 코드를 분석하여 코드 품질 향상