sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo crear una restricción CHECK en SQL Server (ejemplos de T-SQL)

En SQL Server puede crear un CHECK restricción en una tabla para especificar los valores de datos que son aceptables en una o más columnas.

Si una tabla tiene un CHECK restricción en él, e intenta proporcionar datos que no se ajustan al CHECK restricción, la operación fallará con un error.

Esto ayuda a mantener la integridad de los datos, ya que ayuda a evitar que entren en la base de datos datos no válidos.

Cuando creas un CHECK restricción, proporciona una expresión lógica que devuelve TRUE o FALSE . Esta expresión lógica es lo que se usa para verificar los datos.

CHECK Las restricciones son similares a las restricciones de clave externa porque controlan los valores que se colocan en una columna. Sin embargo, la diferencia está en cómo determinan qué valores son válidos:las restricciones de clave externa obtienen la lista de valores válidos de otra tabla, mientras que CHECK las restricciones determinan los valores válidos de una expresión lógica.

Las restricciones se pueden definir a nivel de columna o de tabla. Una restricción de nivel de columna se aplica solo a los datos de esa columna. Una restricción a nivel de tabla se aplica a toda la fila y verifica los datos de varias columnas.

A continuación se muestran ejemplos de creación de CHECK tanto a nivel de columna como a nivel de tabla restricciones.

Ejemplo 1:crear una restricción CHECK a nivel de columna

Aquí hay un ejemplo de cómo crear un CHECK básico a nivel de columna restricción a la hora de crear una tabla.

CREATE TABLE ConstraintTest
(
  ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
  Price smallmoney NOT NULL,
  CONSTRAINT chkPrice CHECK (Price > 0)
);

En este caso, el CHECK restricción especifica que todos los datos en el Price columna debe ser mayor que 0. En otras palabras, el precio no puede ser cero y no puede ser negativo. Esta es una restricción a nivel de columna porque se aplica a los datos de una columna.

Debido a que esta es una restricción a nivel de columna, podría haberla definido como parte de la columna (sin la coma). Así que podría haber hecho esto:

CREATE TABLE ConstraintTest
(
  ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
  Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0)
);

De cualquier manera, intentemos insertar un valor no válido:

INSERT INTO ConstraintTest ( Price )
VALUES ( 0 );

Resultado:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkPrice". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'Price'.

Ejemplo 2:agregar más columnas y otra restricción CHECK a nivel de columna

Agreguemos algunas columnas más a nuestra tabla y luego agreguemos otro CHECK de nivel de columna restricción.

ALTER TABLE ConstraintTest
ADD 
  TeamSize tinyint NOT NULL,
  StartDate date NOT NULL,
  EndDate date NOT NULL,
  CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15)
  ;

Una de las nuevas columnas registra el número de miembros del equipo. En este caso, la regla comercial es que un equipo debe tener al menos 3 miembros, pero no más de 15. Por lo tanto, la base de datos debe evitar la situación en la que un equipo tiene menos de 3 miembros o más de 15.

Intentemos insertar un valor no válido:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 2, '2020-01-01', '1900-02-02' );

Resultado:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.

Ejemplo 3:agregue una restricción CHECK de nivel de tabla

Ahora agreguemos una restricción a nivel de tabla. Esto verificará los datos en dos columnas.

Por cierto, no tienes que agregar otra columna para agregar un CHECK restricción. Simplemente puede agregar la restricción por sí misma.

Ejemplo:

ALTER TABLE ConstraintTest
  ADD CONSTRAINT chkValidEndDate 
  CHECK (EndDate >= StartDate)
  ;

En este caso, agrego una restricción para garantizar que la fecha de finalización nunca sea anterior a la fecha de inicio. Esto es verificar datos en dos columnas y, por lo tanto, es una restricción a nivel de tabla.

Intente insertar un valor no válido:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 3, '2020-01-01', '1900-02-02' );

Resultado:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".

Tenga en cuenta que para probar esta restricción, tuve que aumentar los miembros del equipo a 3 para evitar que la restricción anterior se activara primero (CHECK las restricciones se validan en el orden en que se crean).

Ejemplo 4:modificar una restricción CHECK

En realidad no puedes modificar un CHECK restricción. Si necesita modificarlo, deberá soltarlo y crearlo con la nueva definición.

Ejemplo:

ALTER TABLE ConstraintTest 
  DROP CONSTRAINT chkTeamSize;

ALTER TABLE ConstraintTest
  ADD CONSTRAINT chkTeamSize 
  CHECK (TeamSize >= 5 AND TeamSize <= 20)
  ;

Como se mencionó, CHECK las restricciones se validan en el orden en que se crean, por lo que esto puede afectar qué error se detecta primero.

Por lo tanto, en este caso, si intento insertar un valor no válido (y también incluir fechas no válidas), las fechas no válidas se detectarán primero:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 4, '2020-01-01', '1900-02-02' );

Resultado:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".

Entonces, para verificar mi última restricción, primero tendré que solucionar el problema de la fecha:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 4, '2020-01-01', '2020-02-02' );

Resultado:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.

Así que mi última restricción funciona como se esperaba.

Ejemplo 5:restricciones CHECK y columnas IDENTITY

Ahora que hemos probado las restricciones, sigamos adelante e insertemos datos válidos:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 5, '2020-01-01', '2020-02-02' );

Resultado:

+--------------------+---------+------------+-------------+------------+
| ConstraintTestId   | Price   | TeamSize   | StartDate   | EndDate    |
|--------------------+---------+------------+-------------+------------|
| 13                 | 1.0000  | 5          | 2020-01-01  | 2020-02-02 |
+--------------------+---------+------------+-------------+------------+

Finalmente obtenemos una inserción exitosa.

Sin embargo, notará que la IDENTITY la columna ya ha aumentado a 13.

Recuerde que cuando creé la tabla por primera vez definí el ConstraintTestId columna para usar IDENTITY(1,1) , lo que significa que debe comenzar en 1 e incrementarse automáticamente en 1 con cada inserción de fila.

Pero ahora que finalmente inserté mi primera fila, el valor ya es 13. Eso es porque la IDENTITY columna se incrementa incluso cuando un CHECK la restricción hace que INSERT falla la operación.

Tenga en cuenta que hice algunas inserciones fallidas adicionales mientras creaba los ejemplos para este artículo, por lo que el valor se ha incrementado a un valor más alto que el que obtendrá si simplemente sigue paso a paso este artículo.

En cualquier caso, hagamos una última inserción fallida y luego una exitosa para confirmar esto.

Inserción fallida:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 2, 4, '2020-01-02', '2020-02-03' );

Resultado:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.

Inserción exitosa:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 2, 6, '2020-01-02', '2020-02-03' );

SELECT * FROM ConstraintTest;

Resultado:

+--------------------+---------+------------+-------------+------------+
| ConstraintTestId   | Price   | TeamSize   | StartDate   | EndDate    |
|--------------------+---------+------------+-------------+------------|
| 13                 | 1.0000  | 5          | 2020-01-01  | 2020-02-02 |
| 15                 | 2.0000  | 6          | 2020-01-02  | 2020-02-03 |
+--------------------+---------+------------+-------------+------------+

Podemos ver que la IDENTITY la columna salta de 13 a 15, por lo que obviamente aumentó durante la inserción fallida.

Algunas restricciones de las restricciones CHECK

Aquí hay algunas restricciones a tener en cuenta al trabajar con CHECK restricciones:

  • La condición de búsqueda debe evaluarse como una expresión booleana y no puede hacer referencia a otra tabla.
  • La expresión no puede contener tipos de datos de alias.
  • CHECK no se pueden definir restricciones en texto , ntext o imagen columnas.