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