MySQL 中的 CHECK 约束不起作用
首先,我创建了一个类似的表
CREATE TABLE Customer (
SD integer CHECK (SD > 0),
Last_Name varchar (30),
First_Name varchar(30)
);
,然后在该表中插入了值,
INSERT INTO Customer values ('-2','abc','zz');
MySQL 没有显示错误,它接受了这些值。
First I created a table like
CREATE TABLE Customer (
SD integer CHECK (SD > 0),
Last_Name varchar (30),
First_Name varchar(30)
);
and then inserted values in that table
INSERT INTO Customer values ('-2','abc','zz');
MySQL doesn't show an error, it accepted the values.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
MySQL 8.0.16 是第一个支持 CHECK 约束的版本。
阅读 https://dev.mysql.com/ doc/refman/8.0/en/create-table-check-constraints.html
如果您使用 MySQL 8.0.15 或更早版本,MySQL 参考手册 说:
尝试一下触发器...
MySQL 8.0.16 is the first version that supports CHECK constraints.
Read https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html
If you use MySQL 8.0.15 or earlier, the MySQL Reference Manual says:
Try a trigger...
不幸的是 MySQL 不支持 SQL 检查约束。出于兼容性原因,您可以在 DDL 查询中定义它们,但它们只是被忽略。
有一个简单的替代方案
您可以创建
BEFORE INSERT
和BEFORE UPDATE
触发器,它们会导致错误或在以下情况下将字段设置为其默认值:不满足数据要求。MySQL 5.5 之后的
BEFORE INSERT
示例在 MySQL 5.5 之前,您必须引发错误,例如调用未定义的过程。
在这两种情况下,这都会导致隐式事务回滚。
MySQL 不允许在过程和触发器中使用 ROLLBACK 语句本身。
如果您不想回滚事务(即使“检查约束”失败,INSERT / UPDATE 也应该通过,您可以使用 SET NEW.ID = NULL 覆盖该值,这会将 id 设置为字段默认值,对于 id 来说并没有什么意义
编辑:
删除了杂散的引号。
关于
:=
运算符:https://dev.mysql.com/doc/refman/5.6 /en/assignment-operators.html
关于反引号标识符引号:
http://dev.mysql.com/doc/refman/5.6/en/identifiers.html
Unfortunately MySQL does not support SQL check constraints. You can define them in your DDL query for compatibility reasons but they are just ignored.
There is a simple alternative
You can create
BEFORE INSERT
andBEFORE UPDATE
triggers which either cause an error or set the field to its default value when the requirements of the data are not met.Example for
BEFORE INSERT
working after MySQL 5.5Prior to MySQL 5.5 you had to cause an error, e.g. call a undefined procedure.
In both cases this causes an implicit transaction rollback.
MySQL does not allow the ROLLBACK statement itself within procedures and triggers.
If you don't want to rollback the transaction ( INSERT / UPDATE should pass even with a failed "check constraint" you can overwrite the value using
SET NEW.ID = NULL
which will set the id to the fields default value, doesn't really make sense for an id thoEdit:
Removed the stray quote.
Concerning the
:=
operator:https://dev.mysql.com/doc/refman/5.6/en/assignment-operators.html
Concerning backtick identifier quotes:
http://dev.mysql.com/doc/refman/5.6/en/identifiers.html
MySQL 会忽略
CHECK
约束,如文档中的小注释中所述:创建表
CHECK
constraints are ignored by MySQL as explained in a miniscule comment in the docs:CREATE TABLE
MySQL 中似乎没有实现 CHECK 约束。
请参阅此错误报告: https://bugs.mysql.com/bug.php?id=第3464章
The
CHECK
constraint doesn't seem to be implemented in MySQL.See this bug report: https://bugs.mysql.com/bug.php?id=3464
正如 joanq 所提到的,MariaDB 现在似乎支持 CHECK 约束以及其他好处:
“支持 CHECK CONSTRAINT (MDEV- 7563)。”
https://mariadb.com/kb/en/mariadb/mariadb- 1021-发行说明/
As mentioned by joanq MariaDB now seems to support CHECK constraints among other goodies:
"Support for CHECK CONSTRAINT (MDEV-7563)."
https://mariadb.com/kb/en/mariadb/mariadb-1021-release-notes/
从版本 8.0.15(尚未发布)开始支持检查约束
https:// bugs.mysql.com/bug.php?id=3464
Check constraints are supported as of version 8.0.15 (yet to be released)
https://bugs.mysql.com/bug.php?id=3464
更新到 MySQL 8.0.16 以使用
检查
:MySQL 检查文档
Update to MySQL 8.0.16 to use
checks
:MySQL Checks Documentation
尝试使用
set sql_mode = 'STRICT_TRANS_TABLES'
或SET sql_mode='STRICT_ALL_TABLES'
try with
set sql_mode = 'STRICT_TRANS_TABLES'
ORSET sql_mode='STRICT_ALL_TABLES'