Home > Blockchain >  Can't run NOCHECK CONSTRAINT on mysql - SQL syntax error
Can't run NOCHECK CONSTRAINT on mysql - SQL syntax error

Time:11-01

I've create a table called Students. It has 4 fields: Name, Age, Class, Years.

enter image description here

 ------- ------------- ------ ----- --------- ------- 
| Field | Type        | Null | Key | Default | Extra |
 ------- ------------- ------ ----- --------- ------- 
| Name  | varchar(50) | NO   | PRI | NULL    |       |
| Age   | smallint    | YES  |     | 18      |       |
| Class | varchar(10) | YES  |     | NULL    |       |
| Years | smallint    | YES  |     | NULL    |       |
 ------- ------------- ------ ----- --------- ------- 

I have added a CHECK CONSTRAINT on Years field that means that the value in Years column can't be lower than 3. I did it by

mysql> alter table Students
    -> add constraint CK_Years check (Years >= 3);

My goal here is to insert a query with a record which has a Years value of 2, which means it won't pass the CK_Years check constraint.

I want to do it without changing the constraint or the fields in the insert statement. Is it possible?

mysql> insert into Students
    -> (Name, Age, Class, Years) values ("Eric","25","110","2");

I have tried:

mysql> alter table Students
    -> NOCHECK CONSTRAINT CK_Years;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOCHECK CONSTRAINT CK_Years' at line 2

I want to disable it just for this insert, and then bring it back (the check constraint).

As you can see, I got this error. I tried to write it in couple ways. Wit 'CK_Years' or CK_Years or

`CK_Years`

got the same error for all of these ways.

I have verified that I have the constraint in the table:

mysql> select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    -> where table_name='Students';
 -------------------- ------------------- ----------------- -------------- ------------ ----------------- ---------- 
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
 -------------------- ------------------- ----------------- -------------- ------------ ----------------- ---------- 
| def                | School          | PRIMARY         | School     | Students   | PRIMARY KEY     | YES      |
| def                | School          | CK_Years        | School     | Students   | CHECK           | YES      |
 -------------------- ------------------- ----------------- -------------- ------------ ----------------- ---------- 

So how can I do it without changing the constraint or the fields in the insert statement? How can I fix the syntax error? And what is the reason for it?

Thanks.

CodePudding user response:

MySQL does support syntax to alter a check constraint so it is not enforced, but it's different from the Microsoft SQL Server syntax.

mysql> alter table students alter check CK_Years NOT ENFORCED;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into students values ('Eric',25,'110',2);
Query OK, 1 row affected (0.00 sec)

It's documented here: https://dev.mysql.com/doc/refman/8.0/en/alter-table.html

If you re-enable it, the constraint is enforced, and if you had inserted any rows that violate the constraint, you get an error trying to re-enable it.

mysql> alter table students alter check CK_Years ENFORCED;
ERROR 3819 (HY000): Check constraint 'CK_Years' is violated.

Also once you make the constraint not enforced, it would take effect for all clients, not just for one INSERT.

So I don't think you can do what you intend with a CHECK constraint. You may have to write a trigger that enforces a similar condition on that column, but has logic to enforce it conditionally.

Or do what most developers did before MySQL supported CHECK constraints: enforce it in the client app, before doing the INSERT. Then you can apply any conditions you want.

  • Related