Columnas IDENTITY (Parte 1)

Según los libros en línea () la propiedad IDENTITY Crea una columna de identidad en una tabla. Esta propiedad se usa con las instrucciones CREATE TABLE y ALTER TABLE de Transact-SQL.

Pero, que es una columna de identidad? Es aquella columna que soporta datos numéricos enteros y que se configura para que sus valores se completen automáticamente cada vez que se ingresa un nuevo registro a la tabla. Es decir, al momento de insertar un registro, no debemos preocuparnos del valor de la columna de identidad, ya que SQL Server se va a encargar de asignarle un valor numérico entero.

Hacer clic en la imagen para bajar el script utilizado para los ejemplos:

Primero vamos crear un tabla que contenga una columna de identidad para identificar la sintaxis de creación:

–Creación de tabla utilizando una columna Identity como llave primaria

CREATE TABLE dbo.RastreaOrdenes(

  Id Int IDENTITY(1,1) NOT NULL CONSTRAINT Pk_RastreaOrdenes PRIMARY KEY,

  NroOrden Int NOT NULL,

  FechaOperacion date NOT NULL,

  TextoOperación varchar(50))

GO

Con respecto a la creación de la tabla, obsérvese lo siguiente:

  • El tipo de dato de la columna de identidad es de tipo entero. Se puede optar por los tipos bigint, int, smallint y tinyint (para conocer más sobre los tipos de dato enteros que se pueden utilizar con las columnas IDENTITY, lea el artículo Datos numéricos en SQL Server (Parte 2))
  • La columna IDENTITY se configura con un valor de inicio (Seed o semilla) y un valor de aumento. En este caso hemos utilizado IDENTITY(1,1) Esto quiere decir que la numeración va a iniciar en 1 y va a aumentar de 1 en 1. Esto se puede variar de acuerdo a las necesidades de diseño de la tabla.
  • SQL Server controla internamente el valor que corresponde a cada columna IDENTITY configurada en las diferentes tablas de la base de datos.
  • Una tabla solo puede tener una columna IDENTITY.
  • En este caso en particular, hemos definido que la columna configurada como IDENTITY es la llave primaria, pero esto es opcional. Es decir, no es obligatorio que la columna IDENTITY sea llave primaria.

Habiendo creado la tabla, procedemos a insertar algunos registros:

–Insertar un registro incluyendo un dato en la columna Identity

INSERT INTO dbo.RastreaOrdenes(Id, NroOrden, FechaOperacion, TextoOperación)

VALUES (1, 1054, SYSDATETIME(), ‘Creación de la Orden’)

GO

Obsérvese que en la sentencia de inserción le estamos asignando el valor 1 a la columna “Id” que esta configurada como columna de identidad. Cuando ejecutamos la sentencia parece el siguiente error:

Mens. 544, Nivel 16, Estado 1, Línea 2

No se puede insertar un valor explícito en la columna de identidad de la tabla ‘RastreaOrdenes’ cuando IDENTITY_INSERT es OFF.

Esto sucede por que, cuando configuramos una columna como IDENTITY, la idea es que SQL Server asigne el valor automáticamente. Como indica el mensaje de error, hay una propiedad llamada IDENTITY_INSERT que nos permite definir si podemos o no insertar datos a las columnas configuradas como IDENTITY. Lo normal es que esta propiedad este apagada (OFF), pero más adelante veremos un caso en el que necesitamos encenderla (ON).

Vamos a repetir la sentencia de inserción, pero esta vez no vamos a especificar ningún valor para la columna “Id”:

–Insertar un registro

INSERT INTO dbo.RastreaOrdenes(NroOrden, FechaOperacion, TextoOperación)

VALUES (1054, SYSDATETIME(), ‘Creación de la Orden’)

GO

En este caso la sentenciase ejecutó correctamente. Vamos a consultar la tabla y ver el resultado:

SELECT * FROM dbo.RastreaOrdenes

GO

image

Obsérvese como se ha creado un registro y como la columna “Id” tiene el valor de 1, el cual ha sido asignado automáticamente por SQL Server. Repitamos otra inserción:

–Insertar un registro

INSERT INTO dbo.RastreaOrdenes(NroOrden, FechaOperacion, TextoOperación)

VALUES (1241, SYSDATETIME(), ‘Creación de otra Orden’)

GO

SELECT * FROM dbo.RastreaOrdenes

GO

image

 

Ahora vemos el segundo registro con el numero 2 asignado automáticamente a la columna “Id”. Y así sucederá para todos los registros que se ingresen a la tabla.

Pero hay que tener en cuenta que no siempre la secuencia va a estar completa. Hay algunos casos en los que la secuencia se puede “romper”. Vamos a analizar un ejemplo. Vamos a insertar un registro que no cumpla con alguna de las reglas (Constraint) de la tabla. En este caso vamos a insertar un registro omitiendo el dato para la columna FechaOperación, la cual es obligatoria:

–Inserta registro sin incluir un dato obligatorio, fuerza error de inserción

INSERT INTO RastreaOrdenes(NroOrden, TextoOperación)

VALUES (935, ‘Modificación de la Orden’)

GO

Cuando ejecutamos esta sentencia, aparece el siguiente mensaje de error:

Mens. 515, Nivel 16, Estado 2, Línea 2

No se puede insertar el valor NULL en la columna ‘FechaOperacion’, tabla ‘TestIdentity.dbo.RastreaOrdenes’. La columna no admite valores NULL. Error de INSERT.

Se terminó la instrucción.

 

Esto, como ya indicamos, es por que no incluimos un valor para la columna FechaOperación.

Ahora vamos a insertar otro registro a la tabla, y vamos a consultar los datos:

INSERT INTO dbo.RastreaOrdenes(NroOrden, FechaOperacion, TextoOperación)

VALUES (1328, SYSDATETIME(), ‘Creación de esta Orden’)

GO

 

SELECT * FROM dbo.RastreaOrdenes

GO

image

 

Obsérvese que falta el registro número 3! Que fue lo que sucedió? En la inserción anterior, donde devolvió un error por omitir la columna FechaOperación, a pesar de que no se insertó el registro, SQL Server si aumentó el valor de la llave a 3, el cual ya no se puede reutilizar. Pero eso no debería ser un problema, ya que el objetivo en este caso, es tener un valor de llave que identifique al registro, lo cual se logra aun que la secuencia no esté completa.

Conclusión:

  • Las columnas IDENTITY son Ideales para llaves primarias simples. Hay que tener en cuenta que los datos numéricos enteros son procesados más rápidamente por SQL Server.
  • Tener también en cuenta el rango de llave (valores máximos y mínimos) para seleccionar el tipo de dato entero. Usar un tipo de datos que consuma menos bytes (por ejemplo tinyint) es mejor para el almacenamiento, pero hay que considerar que se pueden acabar los valores disponibles, ya que este tipo de dato ofrece un rango de 0 a 255.
  • Pueden quedar números sin usar o “huecos” y no ser una secuencia completa, pero eso es irrelevante si se trata únicamente de identificar registros como llave primaria.

En un siguiente artículo seguiremos estudiando más este tipo de columna especial y otras aplicaciones y aspectos a tener en cuenta para su uso.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.