Condividi tramite


@@IDENTITY (Transact-SQL)

Si applica a:SQL ServerDatabase SQL di AzureIstanza gestita di SQL di AzureDatabase SQL in Microsoft Fabric

@@IDENTITY è una funzione di sistema che restituisce l'ultimo valore identità inserito.

Convenzioni relative alla sintassi Transact-SQL

Sintassi

@@IDENTITY  

Tipi restituiti

numeric(38,0)

Osservazioni:

Al termine di un'istruzione INSERT, SELECT INTOo di copia bulk, @@IDENTITY contiene l'ultimo valore Identity generato dall'istruzione .

  • Se l'istruzione non ha influenzato nessuna tabella con colonne identità, @@IDENTITY restituisce NULL.
  • Se vengono inserite più righe, generando più valori identità, @@IDENTITY restituisce l'ultimo valore identità generato.
  • Se l'istruzione attiva uno o più trigger che esegueno inserti che generano valori identità, chiamare @@IDENTITY immediatamente dopo l'istruzione restituisce l'ultimo valore identità generato dai trigger.
  • Se un trigger viene attivato dopo un'azione di inserimento in una tabella con una colonna Identity e il trigger inserisce in un'altra tabella che non ha una colonna Identity, @@IDENTITY restituisce il valore Identity del primo inserimento. Il @@IDENTITY valore non viene ripristinato a un'impostazione precedente se l'istruzione o SELECT INTO o la INSERT copia bulk ha esito negativo o se viene eseguito il rollback della transazione.

Le istruzioni e le transazioni con esito negativo sono in grado di modificare i dati Identity correnti di una tabella e creare gap nei valori della colonna Identity. Il valore Identity non viene mai eseguito il rollback anche se non viene eseguito il commit della transazione che ha tentato di inserire il valore nella tabella. Ad esempio, se un'istruzione INSERT ha esito negativo a causa di una IGNORE_DUP_KEY violazione, il valore Identity corrente per la tabella viene comunque incrementato.

@@IDENTITY, SCOPE_IDENTITY, e IDENT_CURRENT sono funzioni simili perché restituiscono tutte l'ultimo valore inserito nella IDENTITY colonna di una tabella.

  • @@IDENTITY e SCOPE_IDENTITY restituire l'ultimo valore identità generato in qualsiasi tabella della sessione corrente. Restituisce SCOPE_IDENTITY tuttavia il valore solo all'interno dell'ambito corrente. @@IDENTITY Non è limitato a un ambito specifico.

  • IDENT_CURRENT non è limitato dall'ambito e dalla sessione; è limitato a una tabella specificata. IDENT_CURRENT restituisce il valore identità generato per una tabella specifica in qualsiasi sessione e in qualsiasi ambito. Per altre informazioni, vedere IDENT_CURRENT (Transact-SQL).

L'ambito della @@IDENTITY funzione è la sessione corrente nel server locale in cui viene eseguita. Questa funzione non può essere applicata a server remoti o collegati. Per ottenere un valore identity in un server diverso, eseguire una stored procedure in tale server remoto o collegato e disporre di tale stored procedure (eseguita nel contesto del server remoto o collegato) raccogliere il valore identity e restituirlo alla connessione chiamante nel server locale.

La replica può influire sul @@IDENTITY valore, perché viene usata all'interno dei trigger di replica e delle stored procedure. @@IDENTITY non è un indicatore affidabile dell'identità creata dall'utente più recente se la colonna fa parte di un articolo di replica. Puoi usare la SCOPE_IDENTITY() sintassi delle funzioni invece di @@IDENTITY. Per altre informazioni, vedere SCOPE_IDENTITY (Transact-SQL).

Nota

La stored procedure chiamante o l'istruzione Transact-SQL deve essere riscritta in modo che usi la funzione SCOPE_IDENTITY(). Verrà così restituito l'ultimo valore Identity usato nell'ambito dell'istruzione utente e non il valore Identity nell'ambito del trigger annidato usato dalla replica.

Esempi

A. Recuperare l'ultimo valore Identity inserito

Nell'esempio seguente viene inserita una riga in una tabella contenente una colonna Identity (LocationID) e viene utilizzata la funzione @@IDENTITY per visualizzare il valore Identity nella nuova riga.

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. Inserire righe padre e figlio usando @@IDENTITY

Nell'esempio seguente viene illustrato l'uso @@IDENTITY di per acquisire il valore Identity di una riga padre e usarlo quando si inseriscono righe figlio correlate. Questo modello è comune nelle progettazioni di tabelle order-entry e padre-figlio.

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

Nota

Nel codice di produzione usare SCOPE_IDENTITY() invece di @@IDENTITY per questo modello. Se un trigger viene attivato nella Orders tabella ed esegue un inserimento in un'altra tabella con una colonna Identity, @@IDENTITY restituisce il valore Identity del trigger anziché il Orders valore Identity. SCOPE_IDENTITY() restituisce solo il valore Identity dell'ambito corrente.

C. Comprendere la differenza tra @@IDENTITY e SCOPE_IDENTITY

L'esempio seguente illustra come @@IDENTITY e SCOPE_IDENTITY() può restituire valori diversi quando sono coinvolti i 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

In questo esempio restituisce SCOPE_IDENTITY() dalla ProductIDProducts tabella (ambito corrente), mentre @@IDENTITY restituisce dalla AuditIDProductAudit tabella (ambito trigger). Per la maggior parte degli scenari dell'applicazione, SCOPE_IDENTITY() è la scelta più sicura perché non è influenzata dall'attività di trigger.