Share via


SR0008: considerare l'utilizzo di SCOPE_IDENTITY anziché @@IDENTITY

RuleId

SR0008

Category

Microsoft.Design

Breaking Change

Non sostanziale

Causa

Il codice contiene una chiamata @@IDENTITY.

Descrizione della regola

Poiché @@IDENTITY è un valore Identity globale, è possibile che sia stato aggiornato all'esterno dell'ambito corrente e che abbia ottenuto un valore imprevisto. I trigger, inclusi i trigger annidati utilizzati dalla replica, possono aggiornare @@IDENTITY all'esterno dell'ambito corrente.

Come correggere le violazioni

Per risolvere questo problema, è necessario sostituire i riferimenti a @@IDENTITY con SCOPE_IDENTITY, il quale restituisce il valore Identity più recente nell'ambito dell'istruzione utente.

Esclusione di avvisi

È possibile evitare la visualizzazione di questo avviso se l'istruzione che utilizza @@IDENTITY viene utilizzata quando si è sicuri che nessun'altra attività di elaborazione abbia aggiornato il valore di @@IDENTITY. È tuttavia consigliabile risolvere l'avviso anziché evitarne la visualizzazione perché SCOPE_IDENTITY fornisce il valore previsto senza il rischio di modifiche non desiderate.

Esempio

Nel primo esempio @@IDENTITY viene utilizzato in una stored procedure che inserisce dati in una tabella. La tabella viene quindi pubblicata per la replica di tipo unione, che prevede l'aggiunta di trigger alle tabelle pubblicate. Di conseguenza, @@IDENTITY può restituire il valore dall'operazione di inserimento in una tabella del sistema di replica anziché dall'operazione di inserimento in una tabella utente.

Il valore di identità massimo della tabella Sales.Customer è 29483. Se si inserisce una riga nella tabella, @@IDENTITY e SCOPE_IDENTITY() restituiscono valori diversi. SCOPE_IDENTITY() restituisce il valore dall'operazione di inserimento nella tabella utente, mentre @@IDENTITY restituisce il valore dall'operazione di inserimento nella tabella del sistema di replica.

Nel secondo esempio viene illustrato come utilizzare SCOPE_IDENTITY() per accedere al valore Identity inserito e come risolvere l'avviso.

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

Vedere anche

Concetti

Analisi del codice di database per migliorare la qualità del codice