Inicio > Sql Server 2005 - 2008, Transact-SQL > Una alternativa para generar identificadores unicos (@@Identity)

Una alternativa para generar identificadores unicos (@@Identity)


— En algunos casos, es necesario obtener un contador sin identity. Y suele hacerse mal,
— lo que genera muchos problemas de bloqueos en situaciones de concurrencia.

— Un ejemplo de lo que NO SE DEBE HACER:

DECLARE @NuevoId INT
SELECT @NuevoId = MAX(Contador) + 1 FROM TablaDatos
INSERT TablaDatos VALUES (@NuevoId, campo2, campo3)
 

— El ejemplo de lo NO SE DEBE HACER, se va a la tabla, se obtiene el mayor valor y se le añade uno.
— Eso significa, más que una fuente de bloqueos, un enorme tapón para la aplicación. 

— Este no es el único problema que puede haber. es frecuente que el contador se obtenga dentro de una transacción.
— Eso si ya seria un verdadero problema.
 

— Se pueden implementar de muchas maneras. Expongo aquí uno basado en una tabla de
— números y en un procedimiento almacenado que encapsula la problemática, al que se le
— pasa como parametro el nombre de la tabla y nos devuelve un nuevo valor.
 

— Creamos la Tabla : 

CREATE TABLE [dbo].[CONTADORES]( [ID] [smallint] IDENTITY(1,1) NOT NULL,[Des_Tabla] [VARCHAR](255) NOT NULL,
[NUM_ID] [INT] NOT NULL,CONSTRAINT [PK_CONTADORES] PRIMARY KEY CLUSTERED ([ID] ASC))
 

— Generemos el Procedimiento Almacenado : 

CREATE PROCEDURE [dbo].[spIdGenerado]
@Des_Tabla Varchar(255),
@NuevoId INT OUTPUT
 

AS
BEGIN
 Set Nocount On
 Declare @Ret INT
 Set Transaction Isolation Level Read Uncommitted
 

 IF @@Trancount > 0
 BEGIN
  Raiserror(‘Error: En transaccin.’, 1, 16)
  Return -998
 END
 

 — Verificar si existe la tabla
 IF Exists(SELECT Des_Tabla FROM Contadores WHERE Des_Tabla = @Des_Tabla)
 BEGIN — Si ya existe, se obtiene el valor generado
  UPDATE Contadores SET @NuevoId = NUM_ID = NUM_ID + 1 FROM Contadores WHERE Des_Tabla = @Des_Tabla
 END
 ELSE
 BEGIN
— Si no existe, se genera la nueva tabla
  SELECT @NuevoId = 1
  INSERT Contadores (DES_Tabla, NUM_ID) VALUES (@Des_Tabla, @NuevoId)
 END
 

 — Control de errores
 SELECT @ret = @@error
 IF @ret <> 0
 BEGIN
  Raiserror(‘Error en la obtención de nuevo identificador’, 1, 16)
  Set Nocount Off
  Return
@ret
 END
 Set Nocount Off
 

 RETURN 0
END
 

— Ejemplo de uso del procedimiento : 

EXEC spIdGenerado ‘Tabla’,0 

— Se incluye la sentencia que impedirá que se llame al procedimiento con una transacción de por medio.
— Es una medida de precaución necesario y eficaz.
— El procedimiento se ocupa de generar un identificador para la descripción de la tabla.

  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: