Sdílet prostřednictvím


@@IDENTITY (Transact-SQL)

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL databáze v Microsoft Fabric

@@IDENTITY je systémová funkce, která vrací poslední vloženou identitní hodnotu.

Transact-SQL konvence syntaxe

Syntaxe

@@IDENTITY  

Návratové typy

numerické(38,0)

Poznámky

INSERTPo dokončení @@IDENTITY příkazu , SELECT INTOnebo hromadné kopírování obsahuje poslední hodnotu identity, kterou příkaz vygeneroval.

  • Pokud příkaz neovlivnil žádné tabulky s identitními sloupci, @@IDENTITY vrátí NULL.
  • Pokud je vloženo více řádků, generuje se více hodnot identity, @@IDENTITY vrátí se poslední vygenerovaná hodnota identity.
  • Pokud příkaz spustí jeden nebo více spouštěčů, které provedou vložení generující hodnoty identity, volání @@IDENTITY ihned po příkazu vrátí poslední hodnotu identity generovanou spouštěči.
  • Pokud se trigger aktivuje po akci vložení v tabulce se sloupcem identity a trigger se vloží do jiné tabulky, která nemá sloupec identity, @@IDENTITY vrátí hodnotu identity prvního vložení. Hodnota @@IDENTITY se nevrátí k předchozímu nastavení, pokud INSERT selže příkaz nebo SELECT INTO hromadná kopie nebo pokud se transakce vrátí zpět.

Neúspěšné příkazy a transakce mohou změnit aktuální identitu tabulky a vytvořit mezery v hodnotách sloupců identity. Hodnota identity se nikdy nevrátila zpět, i když transakce, která se pokusila vložit hodnotu do tabulky, není potvrzena. Pokud například INSERT příkaz selže z důvodu IGNORE_DUP_KEY porušení, aktuální hodnota identity tabulky se stále zvýší.

@@IDENTITY, SCOPE_IDENTITY, a IDENT_CURRENT jsou podobné funkce, protože všechny vracejí poslední hodnotu vloženou IDENTITY do sloupce tabulky.

  • @@IDENTITY a SCOPE_IDENTITY vrať poslední hodnotu identity generovanou v libovolné tabulce v aktuální relaci. SCOPE_IDENTITY Vrátí však hodnotu pouze v rámci aktuálního oboru; @@IDENTITY není omezena na konkrétní obor.

  • IDENT_CURRENT není omezena oborem a relací; je omezena na zadanou tabulku. IDENT_CURRENT vrací identitní hodnotu generovanou pro konkrétní tabulku v jakékoli relaci a v jakémkoli rozsahu. Pro více informací viz IDENT_CURRENT (Transact-SQL).

Oborem @@IDENTITY funkce je aktuální relace na místním serveru, na kterém běží. Tuto funkci nelze použít na vzdálené nebo propojené servery. Pokud chcete získat hodnotu identity na jiném serveru, spusťte na tomto vzdáleném nebo propojeném serveru uloženou proceduru a shromážděte hodnotu identity (která běží v kontextu vzdáleného nebo propojeného serveru) a vraťte ji do volajícího připojení na místním serveru.

Replikace může ovlivnit @@IDENTITY hodnotu, protože se používá v rámci triggerů replikace a uložených procedur. @@IDENTITY není spolehlivým indikátorem nejnovější identity vytvořené uživatelem, pokud je sloupec součástí článku replikace. Můžete použít syntaxi SCOPE_IDENTITY() funkce místo .@@IDENTITY Další informace najdete v tématu SCOPE_IDENTITY (Transact-SQL).

Poznámka:

Volající uložená procedura nebo Transact-SQL příkaz musí být přepsán tak, aby používal funkci SCOPE_IDENTITY() , která vrací nejnovější identitu použitou v rozsahu uživatelského příkazu, nikoli identitu v rozsahu vnořeného spouštěče používaného replikací.

Examples

A. Načtení hodnoty poslední vložené identity

Následující příklad vloží řádek do tabulky s identifikačním sloupcem (LocationID) a použije @@IDENTITY ho k zobrazení hodnoty identity použité v novém řádku.

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. Vložení nadřazených a podřízených řádků pomocí @@IDENTITY

Následující příklad ukazuje použití @@IDENTITY k zachycení hodnoty identity nadřazeného řádku a jeho použití při vložení souvisejících podřízených řádků. Tento vzor je běžný v návrhech tabulek s pořadím a nadřazeným podřízeným vzorem.

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

Poznámka:

V produkčním kódu použijte SCOPE_IDENTITY() místo @@IDENTITY tohoto vzoru. Pokud se trigger aktivuje v Orders tabulce a provede vložení do jiné tabulky se sloupcem identity, @@IDENTITY vrátí hodnotu identity triggeru Orders místo hodnoty identity. SCOPE_IDENTITY() vrátí pouze hodnotu identity z aktuálního oboru.

C. Vysvětlení rozdílu mezi @@IDENTITY a SCOPE_IDENTITY

Následující příklad ukazuje, jak @@IDENTITY a SCOPE_IDENTITY() může vrátit různé hodnoty při zapojení triggerů.

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

V tomto příkladu SCOPE_IDENTITY()Products vrátí ProductID hodnotu z tabulky (aktuální obor), zatímco @@IDENTITY vrátí AuditID z tabulky (obor triggeruProductAudit). U většiny scénářů aplikací je bezpečnější volba, SCOPE_IDENTITY() protože na ni nemá vliv aktivita triggeru.