unicas - tipos de restricciones en mysql
Usar una declaración de caso en una restricción de verificación (3)
Creo que puedes hacer lo siguiente:
CREATE TABLE Grade
(
salary_grade char(1) NOT NULL CHECK (REGEXP_LIKE(salary_grade, ''[A-G]'', ''c'')),
salary_scale char(2) DEFAULT ''S1'' NOT NULL,
CONSTRAINT pk_grade PRIMARY KEY (salary_grade),
CONSTRAINT ck_grade_scale CHECK ( REGEXP_LIKE(salary_grade, ''[A-D]'', ''c'') AND salary_scale = ''S1''
OR REGEXP_LIKE(salary_grade, ''[E-G]'', ''c'') AND salary_scale = ''S2'' )
);
Por favor, consulte el esquema SQL Fiddle aquí.
No necesita la restricción UPPER()
en salary_grade
ya que la verificación de salary_grade
regulares será suficiente (ya está comprobando para asegurarse de que sea una letra mayúscula entre A y G). No creo que la restricción en salary_scale
sí sola sea necesaria tampoco, ya que estaría contenida, lógicamente, en la última restricción.
ACTUALIZAR
Aquí es cómo puede hacerlo con una declaración CASE
:
CREATE TABLE Grade
(
salary_grade char(1) NOT NULL CHECK (REGEXP_LIKE(salary_grade, ''[A-G]'', ''c'')),
salary_scale char(2) DEFAULT ''S1'' NOT NULL,
CONSTRAINT pk_grade PRIMARY KEY (salary_grade),
CONSTRAINT ck_grade_scale CHECK ( salary_scale = CASE WHEN REGEXP_LIKE(salary_grade, ''[A-D]'', ''c'') THEN ''S1'' ELSE ''S2'' END )
);
He estado aprendiendo SQL durante la última semana, pero no estoy seguro de cómo agregar correctamente una declaración de caso dentro de una restricción de verificación. ¿Alguien puede darme algún consejo?
Tengo la siguiente tabla de calificaciones:
CREATE TABLE Grade
(
salary_grade char(1) NOT NULL CHECK (salary_grade = UPPER(salary_grade)),
CONSTRAINT ck_grade_scale CHECK(
CASE
WHEN salary_grade = ''[A-D]''
THEN salary_scale = ''S1''
WHEN salary_grade = ''[D-G]''
THEN salary_scale = ''S2''
END)
salary_scale char(2) DEFAULT ''S1'' NOT NULL,
CONSTRAINT pk_grade PRIMARY KEY (salary_grade),
CONSTRAINT ck_salary_grade CHECK (REGEXP_LIKE(salary_grade, ''[A-G]'', ''c'')),
--constraint must be either S1 or S2
CONSTRAINT ck_salary_scale CHECK (salary_scale IN (''S1'', ''S2''))
);
Quiero comprobar que si el salary_grade
encuentra entre AD, entonces la salary_scale
debe ser ''S1'' o si el salary_grade
está entre EG, entonces es ''S2''.
He tratado de investigar esto y presentar esto último, pero sin embargo no funciona ... ¿he estructurado el código correctamente?
Un case
tiene que ser comparado con algo, por lo que está obteniendo el error de paréntesis correcto que falta. A menos que desee un case
particular, puede verificar la combinación con y / o:
CONSTRAINT ck_grade_scale CHECK(
(salary_grade BETWEEN ''A'' AND ''D'' AND salary_scale = ''S1'')
OR (salary_grade BETWEEN ''D'' AND ''G'' AND salary_scale = ''S2'')),
Como ha dicho Parado, no puede usar restricciones para establecer valores de columna condicionalmente, solo para restringirlos. Podría utilizar una columna virtual para la escala, pero significaría poner parte de una tabla de búsqueda en el DDL en lugar de los datos, lo que parece un poco extraño.
Check Constraints
se usa para probar los datos antes de insertarlos para proteger la estructura de datos de datos falsos. En realidad usamos el case
en la declaración select
. No puede usarlo para inserción condicional . Si desea cambiar los datos de una columna particular antes de la inserción, debe usar el trigger
o también puede usar virtual column
pero que tiene algunas restricciones.
Más información que puedes encontrar aquí