sábado, 23 de enero de 2016

Unique constraints y check constraints en SQL Server

Son dos tipos de restricciones que pueden ser utilizadas para hacer cumplir la integridad de datos en tablas de SQL Server. Estos son objetos importantes en las bases de datos y sustituyen a las antiguas reglas y su instrucción CREATE RULE. Las restricciones son reglas que la base de datos hace cumplir. Por ejemplo, la restricción UNIQUE sirve para asegurarse que no se introduzcan valores duplicados en columnas específicas que no pertenecen a una clave principal. La restricción UNIQUE  se debe crear siguiendo los siguientes criterios:


UNIQUE CONSTRAINTS Y CHECK CONSTRAINTS


Utilizaremos una restricción UNIQUE en lugar de una restricción PRIMARY KEY cuando se desea hacer cumplir la singularidad de una columna o combinación de columnas, que no sean la clave principal. Al contrario que PRIMARY KEY, la restricción UNIQUE permite tomar el valor NULL. Sin embargo, como sucede con cualquier valor de una restricción UNIQUE, sólo se permitirá un valor nulo en cada columna.

Cuando se agrega una restricción UNIQUE a una columna o columnas existentes en la tabla, el motor de la base de datos base examina los datos existentes en las columnas para asegurarse de que todos los valores son únicos. Si se añade una restricción UNIQUE a una columna que ya tiene valores duplicados, se producirá un error y no será posible añadir la restricción. A menos que se especifique explícitamente un índice CLUSTERED, se creará automáticamente  un índice UNCLUSTERED y único para hacer cumplir la restricción UNIQUE. De los índices se hablará en artículos posteriores.

Restricciones CHECK

Este tipo de restricciones se ocupan de hacer cumplir la integridad de dominio mediante la limitación de los valores que son aceptados por una o más columnas. Es posible crear una restricción de tipo CHECK con cualquier expresión lógica (booleana) que devuelva TRUE o FALSE en base a los operadores lógicos.

Por ejemplo, el rango de valores para una columna de salario puede limitarse mediante la creación de una restricción CHECK que permite sólo los datos que vayan  desde 10.000 € hasta 50.000 €. Esto evita que las cantidades introducidas en esta columna estén fuera de este rango.

Se pueden aplicar varias restricciones CHECK a una sola columna. También es posible aplicar una única restricción CHECK de varias columnas a nivel de tabla. Esto permite múltiples condiciones que deben verificarse en un solo lugar.

Las restricciones CHECK son similares a restricciones FOREIGN la diferencia está en cómo se determinan qué valores son válidos. Las restricciones FOREIGN KEY obtienen la lista de valores válidos de otra tabla, mientras que las restricciones CHECK determinar los valores válidos a partir de una expresión lógica.

Las restricciones CHECK rechazan los valores que evalúan como FALSE. Debido a que los valores nulos se evalúan como desconocidos, su inclusión en las expresiones puede anular una restricción.
Por ejemplo, si ponemos una restricción en una columna llamada NombreColumna que sólo le permita tomar el valor 10 con un tipo de datos int de tal forma que NombreColumna sólo puede contener el valor 10. Si insertamos  el valor NULL en NombreColumna, se insertará efectivamente un  NULL y no devolverá error.
Una restricción CHECK devuelve TRUE cuando la condición se está comprobando que no es FALSE para cualquier fila de la tabla. Una restricción CHECK trabaja en el nivel de fila. Si una tabla que acaba de ser creada no tiene ninguna fila, cualquier restricción CHECK en esta tabla es  considerada válida. Esta situación puede producir resultados inesperados, como en el siguiente ejemplo.

CREATE TABLE TbNombreTabla (columna1 int, columna2 int);
GO
CREATE FUNCTION FnCheckTabla()
RETURNS int
AS
BEGIN
   DECLARE @valorretorno int
   SELECT @valorretorno = COUNT(*) FROM TbNombreTabla
   RETURN @valorretorno
END;
GO
ALTER TABLE TbNombreTabla
ADD CONSTRAINT chkCuentaFilas CHECK (dbo.FnCheckTabla () >= 1);
GO

La restricción CHECK que se añade especifica que debe haber al menos una fila en la tabla TbNombreTablaLas restricciones CHECK no se validan durante las sentencias DELETE. Por lo tanto, la ejecución de sentencias DELETE en tablas con ciertos tipos de restricciones de comprobación pueden producir resultados inesperados. Por ejemplo, consideremos las siguientes sentencias ejecutadas en la tabla TbNombreTabla.

INSERT INTO dbo.tbNombreTabla VALUES (10, 10);
GO
DELETE dbo.tbNombreTabla WHERE columna1 = 10;

La sentencia DELETE tiene éxito, aunque la restricción CHECK especifica que la tabla tbNombreTabla debe tener al menos 1 fila.

Valores por defecto

DEFAULT.
Especifica el valor que tomará la columna cuando no se especifique explícitamente un valor para esta columna durante una inserción. La cláusula DEFAULT se puede aplicar a cualquier columna, excepto a las definidas como timestamp o a las que tengan la propiedad IDENTITY. Para una columna de un tipo definido por el usuario, dicho tipo deberá ser compatible con la conversión implícita de la constante utilizada en el tipo definido por el usuario.
El valor predeterminado sólo puede consistir en un valor constante, por ejemplo una cadena de caracteres, una función escalar (función del sistema, definida por el usuario) o NULL. Para mantener la compatibilidad con las versiones anteriores de SQL Server, puede asignar un nombre de restricción a DEFAULT.

IDENTITY  
Indica que la nueva columna es una columna de identidad. Cuando se agrega una fila nueva a la tabla, el Motor de base de datos proporciona un valor incremental único para la columna. Las columnas de identidad se utilizan normalmente con las restricciones PRIMARY KEY como identificadores de fila únicos para la tabla. La propiedad IDENTITY se puede asignar a columnas de los tipos tinyint, smallint, int, bigint, decimal(p,0) o numeric(p,0). Sólo se puede crear una columna de identidad para cada tabla. Aquí 
hay un ejemplo de cómo añadir un campo IDENTITY a una tabla. Las restricciones DEFAULT no se pueden utilizar en las columnas de identidad. En este caso, deben especificarse el valor de inicialización y el incremento, o ninguno de esto valores. Si no se especifica ninguno, el valor predeterminado es (1,1).
En una tabla con optimización para memoria, el único valor permitido tanto para seed como para increment es 1; (1,1) es el valor predeterminado para seed e increment.

Seed.  Es el valor que se utiliza para la primera fila cargada en la tabla.

Increment. Es el valor incremental que se agrega al valor de identidad de la fila cargada anterior. 

No hay comentarios:

Publicar un comentario