Dela via


@@IDENTITY (Transact-SQL)

Gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-databas i Microsoft Fabric

@@IDENTITY är en systemfunktion som returnerar det senast insatta identitetsvärdet.

Transact-SQL syntaxkonventioner

Syntax

@@IDENTITY  

Returtyper

numerisk(38,0)

Anmärkningar

När en INSERT, SELECT INTO, eller masskopieringsinstrukation har slutförts innehåller @@IDENTITY den sista identitetsvärdet som -instruktionen genererade.

  • Om satsen inte påverkade några tabeller med identitetskolumner, @@IDENTITY returnerar NULL.
  • Om flera rader infogas, vilket genererar flera identitetsvärden, @@IDENTITY returnerar det senaste identitetsvärdet som genereras.
  • Om satsen utlöser en eller flera triggers som utför insättningar som genererar identitetsvärden, returnerar anrop @@IDENTITY omedelbart efter uttalandet det senaste identitetsvärdet som genererats av triggers.
  • Om en utlösare utlöses efter en infogningsåtgärd i en tabell som har en identitetskolumn och utlösaren infogas i en annan tabell som inte har en identitetskolumn, @@IDENTITY returnerar identitetsvärdet för den första infogningen. Värdet @@IDENTITY återgår inte till en tidigare inställning om instruktionen eller SELECT INTO -instruktionen INSERT eller masskopian misslyckas, eller om transaktionen återställs.

Misslyckade satser och transaktioner kan ändra den aktuella identiteten för en tabell och skapa luckor i identitetskolumnens värden. Identitetsvärdet återställs aldrig trots att transaktionen som försökte infoga värdet i tabellen inte har checkats in. Om en INSERT instruktion till exempel misslyckas på grund av en IGNORE_DUP_KEY överträdelse ökar fortfarande tabellens aktuella identitetsvärde.

@@IDENTITY, SCOPE_IDENTITY, och IDENT_CURRENT är liknande funktioner eftersom de alla returnerar det sista värdet som satts in i kolumnen IDENTITY i en tabell.

  • @@IDENTITY och SCOPE_IDENTITY returnera det senaste identitetsvärdet som genererats i någon tabell i den aktuella sessionen. Returnerar dock SCOPE_IDENTITY endast värdet inom det aktuella omfånget. @@IDENTITY Det är inte begränsat till ett specifikt omfång.

  • IDENT_CURRENT begränsas inte av omfång och session. den är begränsad till en angiven tabell. IDENT_CURRENT returnerar identitetsvärdet som genererats för en specifik tabell i varje session och i varje scope. För mer information, se IDENT_CURRENT (Transact-SQL).

Funktionens @@IDENTITY omfång är den aktuella sessionen på den lokala server där den körs. Den här funktionen kan inte tillämpas på fjärrservrar eller länkade servrar. Om du vill hämta ett identitetsvärde på en annan server kör du en lagrad procedur på den fjärrservern eller den länkade servern och har den lagrade proceduren (som körs i kontexten för den fjärranslutna eller länkade servern) samla in identitetsvärdet och returnera det till den anropande anslutningen på den lokala servern.

Replikering kan påverka @@IDENTITY värdet eftersom det används i replikeringsutlösarna och lagrade procedurer. @@IDENTITY är inte en tillförlitlig indikator på den senaste användarskapade identiteten om kolumnen är en del av en replikeringsartikel. Du kan använda SCOPE_IDENTITY() funktionssyntaxen istället för @@IDENTITY. Mer information finns i SCOPE_IDENTITY (Transact-SQL).

Anmärkning

Den anropande lagrade proceduren eller Transact-SQL-satsen måste skrivas om för att använda SCOPE_IDENTITY() funktionen, som returnerar den senaste identiteten som användes inom användarsatsens omfattning, och inte identiteten inom omfattningen av den nästlade triggern som används vid replikering.

Examples

A. Hämta det senast infogade identitetsvärdet

Följande exempel infogar en rad i en tabell med en identitetskolumn (LocationID) och använder @@IDENTITY det för att visa identitetsvärdet som används i den nya raden.

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. Infoga överordnade och underordnade rader med hjälp av @@IDENTITY

I följande exempel visas hur du använder @@IDENTITY för att avbilda en överordnad rads identitetsvärde och använda det när du infogar relaterade underordnade rader. Det här mönstret är vanligt i tabelldesignen order-entry och parent-child.

-- 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

Anmärkning

Använd i stället för @@IDENTITY för det här mönstret i produktionskodenSCOPE_IDENTITY(). Om en utlösare utlöses i Orders tabellen och utför en infogning i en annan tabell med en identitetskolumn returnerar @@IDENTITY utlösarens identitetsvärde i stället för identitetsvärdet Orders . SCOPE_IDENTITY() returnerar endast identitetsvärdet från det aktuella omfånget.

C. Förstå skillnaden mellan @@IDENTITY och SCOPE_IDENTITY

I följande exempel visas hur @@IDENTITY och SCOPE_IDENTITY() kan returnera olika värden när utlösare är inblandade.

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

I det här exemplet SCOPE_IDENTITY() returnerar ProductID från Products tabellen (aktuellt omfång) medan @@IDENTITY returnerar AuditID från ProductAudit tabellen (utlösaromfånget). I de flesta programscenarier SCOPE_IDENTITY() är det säkrare valet eftersom det inte påverkas av utlösaraktivitet.