적용 대상:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Microsoft Fabric의 SQL 데이터베이스
@@IDENTITY 는 마지막으로 삽입된 항등성 값을 반환하는 시스템 함수입니다.
구문
@@IDENTITY
반환 형식
numeric(38,0)
설명
INSERT또는 SELECT INTO대량 복사 문이 완료 @@IDENTITY 된 후 문이 생성한 마지막 ID 값을 포함합니다.
- 만약 문장이 항등성 열을 가진 테이블에 영향을 미치지 않았다면,
@@IDENTITY를 반환합니다NULL. - 여러 행이 삽입되어 여러 정체성 값이 생성되면,
@@IDENTITY마지막으로 생성된 정체성 값을 반환합니다. - 문장이 하나 이상의 트리거를 발동하여 삽입하여 식별 값을 생성하면, 문장 직후 호출
@@IDENTITY하면 트리거가 생성한 마지막 식별 값을 반환합니다. - ID 열이 있는 테이블에서 삽입 작업 후에 트리거가 실행되고 트리거가 ID 열
@@IDENTITY이 없는 다른 테이블에 삽입하는 경우 첫 번째 삽입의 ID 값을 반환합니다.@@IDENTITY또는 문 또는 대량 복사가 실패하거나SELECT INTO트랜잭션이 롤백되는 경우INSERT값은 이전 설정으로 되돌아가지 않습니다.
문 및 트랜잭션이 실패해도 테이블의 현재 ID가 변경되고 ID 열 값 간에 간격이 생성될 수 있습니다. 테이블에 값을 삽입하려는 트랜잭션이 커밋되지 않더라도 ID 값은 롤백되지 않습니다. 예를 들어 위반으로 INSERT 인해 문이 실패하는 경우 테이블의 IGNORE_DUP_KEY 현재 ID 값은 계속 증가합니다.
@@IDENTITY
SCOPE_IDENTITY, , IDENT_CURRENT , 는 모두 테이블의 열에 IDENTITY 삽입된 마지막 값을 반환하기 때문에 유사한 함수입니다.
@@IDENTITY그리고SCOPE_IDENTITY현재 세션 내 임의의 테이블에서 생성된 마지막 정체성 값을 반환합니다. 그러나SCOPE_IDENTITY현재 범위 내에서만 값을 반환하며@@IDENTITY특정 범위로 제한되지는 않습니다.IDENT_CURRENT는 범위 및 세션에 의해 제한되지 않습니다. 지정된 테이블로 제한됩니다.IDENT_CURRENT특정 세션과 범위에서 생성된 정체성 값을 반환합니다. 자세한 내용은 IDENT_CURRENT(Transact-SQL)를 참조하세요.
함수의 @@IDENTITY 범위는 함수가 실행되는 로컬 서버의 현재 세션입니다. 이 함수는 원격 또는 연결된 서버에 적용할 수 없습니다. 다른 서버에서 ID 값을 가져오려면 해당 원격 또는 연결된 서버에서 저장 프로시저를 실행하고 해당 저장 프로시저(원격 또는 연결된 서버의 컨텍스트에서 실행)가 ID 값을 수집하고 로컬 서버의 호출 연결로 반환하도록 합니다.
복제는 복제 트리거 및 저장 프로시저 내에서 사용되므로 값에 영향을 줄 @@IDENTITY 수 있습니다.
@@IDENTITY 은 열이 복제 문서의 일부인 경우 가장 최근 사용자가 만든 ID의 신뢰할 수 있는 지표가 아닙니다. 함수 구문을 SCOPE_IDENTITY()사용할 @@IDENTITY 수 있습니다. 자세한 내용은 SCOPE_IDENTITY(Transact-SQL)를 참조하세요.
참고
복제에 사용되는 중첩 트리거 범위 내의 ID가 아니라 해당 사용자 명령문의 범위 내에서 사용되는 최신 ID를 반환할 SCOPE_IDENTITY() 함수를 사용하도록 호출하는 저장 프로시저 또는 Transact-SQL 문을 다시 작성해야 합니다.
예제
A. 마지막으로 삽입한 ID 값 검색
다음 예에서는 ID 열(LocationID)이 있는 테이블에 행을 삽입하고 @@IDENTITY를 사용하여 새 행에 사용된 ID 값을 표시합니다.
USE AdventureWorks2022;
GO
--Display the value of LocationID in the last row in the table.
SELECT MAX(LocationID) FROM Production.Location;
GO
INSERT INTO Production.Location (Name, CostRate, Availability, ModifiedDate)
VALUES ('Damaged Goods', 5, 2.5, GETDATE());
GO
SELECT @@IDENTITY AS 'Identity';
GO
--Display the value of LocationID of the newly inserted row.
SELECT MAX(LocationID) FROM Production.Location;
GO
B. @@IDENTITY 사용하여 부모 및 자식 행 삽입
다음 예제에서는 부모 행의 ID 값을 캡처하고 관련 자식 행을 삽입할 때 사용하는 방법을 보여 @@IDENTITY 줍니다. 이 패턴은 순서 항목 및 부모-자식 테이블 디자인에서 일반적입니다.
-- Create sample tables
CREATE TABLE dbo.Orders (
OrderID int IDENTITY(1, 1) PRIMARY KEY,
CustomerName nvarchar(100) NOT NULL,
OrderDate datetime NOT NULL DEFAULT GETDATE()
);
CREATE TABLE dbo.OrderDetails (
DetailID int IDENTITY(1, 1) PRIMARY KEY,
OrderID int NOT NULL REFERENCES dbo.Orders(OrderID),
ProductName nvarchar(100) NOT NULL,
Quantity int NOT NULL
);
GO
-- Insert a parent row and capture its identity
INSERT INTO dbo.Orders (CustomerName, OrderDate)
VALUES ('Contoso Ltd', GETDATE());
DECLARE @NewOrderID int = @@IDENTITY;
-- Insert child rows using the captured parent identity
INSERT INTO dbo.OrderDetails (OrderID, ProductName, Quantity)
VALUES (@NewOrderID, 'Widget A', 10);
INSERT INTO dbo.OrderDetails (OrderID, ProductName, Quantity)
VALUES (@NewOrderID, 'Widget B', 5);
-- Verify the results
SELECT o.OrderID, o.CustomerName, d.ProductName, d.Quantity
FROM dbo.Orders o
INNER JOIN dbo.OrderDetails d ON o.OrderID = d.OrderID
WHERE o.OrderID = @NewOrderID;
GO
참고
프로덕션 코드에서 이 패턴 대신 @@IDENTITY 사용합니다SCOPE_IDENTITY(). 트리거가 테이블에서 실행 Orders 되고 ID 열 @@IDENTITY 이 있는 다른 테이블에 삽입을 수행하는 경우 ID 값 대신 Orders 트리거의 ID 값을 반환합니다.
SCOPE_IDENTITY() 는 현재 범위에서 ID 값만 반환합니다.
C. @@IDENTITY SCOPE_IDENTITY 간의 차이점 이해
다음 예제에서는 트리거가 SCOPE_IDENTITY() 관련될 때 다른 값을 반환하는 방법과 @@IDENTITY 방법을 보여 줍니다.
CREATE TABLE dbo.Products (
ProductID int IDENTITY(1, 1) PRIMARY KEY,
ProductName nvarchar(100) NOT NULL
);
CREATE TABLE dbo.ProductAudit (
AuditID int IDENTITY(1000, 1) PRIMARY KEY,
ProductID int NOT NULL,
AuditAction nvarchar(50) NOT NULL,
AuditDate datetime NOT NULL DEFAULT GETDATE()
);
GO
-- Create a trigger that inserts into ProductAudit
CREATE TRIGGER trg_ProductInsert
ON dbo.Products
AFTER INSERT
AS
BEGIN
INSERT INTO dbo.ProductAudit (ProductID, AuditAction)
SELECT ProductID, 'INSERT'
FROM inserted;
END;
GO
-- Insert a product and compare identity values
INSERT INTO dbo.Products (ProductName) VALUES ('Test Product');
SELECT @@IDENTITY AS [@@IDENTITY],
SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
GO
이 예제 SCOPE_IDENTITY() 에서는 테이블(현재 범위)에서 Products 값을 반환 ProductAuditProductIDAuditID 하고 @@IDENTITY 테이블에서 반환합니다(트리거 범위). 대부분의 애플리케이션 시나리오에서는 SCOPE_IDENTITY() 트리거 작업의 영향을 받지 않으므로 더 안전한 선택입니다.