SR0008: Usar SCOPE_IDENTITY en lugar de @@IDENTITY

Identificador de regla

SR0008

Categoría

Microsoft.Design

Cambio problemático

Poco problemático

Causa

El código contiene una llamada a @@IDENTITY.

Descripción de la regla

Dado que @@IDENTITY es un valor de identidad global, podría haberse actualizado fuera del ámbito actual y haber obtenido un valor inesperado. Los desencadenadores, incluidos los desencadenadores anidados que utiliza la replicación, pueden actualizar @@IDENTITY fuera del ámbito actual.

Cómo corregir infracciones

Para resolver este problema debe reemplazar las referencias a @@IDENTITY con SCOPE_IDENTITY, que devuelve el valor de identidad más reciente en el ámbito de la instrucción de usuario.

Cuándo suprimir advertencias

Puede suprimir esta advertencia si la instrucción que usa @@IDENTITY se utiliza cuando existe la certeza de que ningún otro procesamiento puede haber actualizado el valor de @@IDENTITY. Sin embargo, se recomienda encarecidamente resolver la advertencia en lugar de suprimirla porque SCOPE_IDENTITY proporciona el valor previsto sin riesgo de cambios inesperados.

Ejemplo

En el primer ejemplo, @@IDENTITY se usa en un procedimiento almacenado que inserta datos en una tabla. Después la tabla se publica para la replicación de mezcla, que agrega desencadenadores a las tablas que se publican. Por tanto, @@IDENTITY puede devolver el valor de la operación de inserción en una tabla del sistema de replicación en lugar de la operación de inserción en una tabla de usuario.

La tabla Sales.Customer tiene un valor de identidad máximo de 29483. Si inserta una fila en la tabla, @ @ IDENTIDAD y SCOPE_IDENTITY () devuelven valores diferentes. SCOPE_IDENTITY() devuelve el valor de la operación de inserción en la tabla de usuario, pero @@IDENTITY devuelve el valor de la operación de inserción en la tabla de sistema de replicación.

El segundo ejemplo muestra cómo puede utilizar SCOPE_IDENTITY() para tener acceso al valor de identidad insertado y resolver la advertencia.

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

Vea también

Conceptos

Analizar el código de base de datos para mejorar la calidad del código