MySQL中的检查约束不起作用
首先,我创建了一个表,如MySQL中的检查约束不起作用,mysql,check-constraints,Mysql,Check Constraints,首先,我创建了一个表,如 CREATE TABLE Customer ( SD integer CHECK (SD > 0), Last_Name varchar (30), First_Name varchar(30) ); 然后在表中插入值 INSERT INTO Customer values ('-2','abc','zz'); MySQL没有显示错误,它接受了值。MySQL中似乎没有实现检查约束 请参阅此错误报告:是第一个支持检查约束的版本 阅读 如果您使用MyS
CREATE TABLE Customer (
SD integer CHECK (SD > 0),
Last_Name varchar (30),
First_Name varchar(30)
);
然后在表中插入值
INSERT INTO Customer values ('-2','abc','zz');
MySQL没有显示错误,它接受了值。MySQL中似乎没有实现
检查约束
请参阅此错误报告:是第一个支持检查约束的版本
阅读
如果您使用MySQL 8.0.15或更早版本,则会显示:
CHECK
子句已被解析,但被所有存储引擎忽略
试试扳机
mysql> delimiter //
mysql> CREATE TRIGGER trig_sd_check BEFORE INSERT ON Customer
-> FOR EACH ROW
-> BEGIN
-> IF NEW.SD<0 THEN
-> SET NEW.SD=0;
-> END IF;
-> END
-> //
mysql> delimiter ;
mysql>分隔符//
mysql>在插入客户之前创建触发器触发器sd检查
->每行
->开始
->如果NEW.SD设置为NEW.SD=0;
->如果结束;
->结束
-> //
mysql>分隔符;
希望能有所帮助。尝试使用设置sql\u模式='STRICT\u TRANS\u TABLES'
或设置sql\u模式='STRICT\u ALL\u TABLES'
检查约束被MySQL忽略,如文档中的一条小注释所述:
CHECK
子句已被解析,但被所有存储引擎忽略
不幸的是,MySQL不支持SQL检查约束。出于兼容性原因,您可以在DDL查询中定义它们,但它们只是被忽略了
有一个简单的选择
您可以创建插入前和更新前触发器,当数据要求不满足时,这些触发器会导致错误或将字段设置为默认值
插入之前的示例
在MySQL 5.5之后工作
DELIMITER $$
CREATE TRIGGER `test_before_insert` BEFORE INSERT ON `Test`
FOR EACH ROW
BEGIN
IF CHAR_LENGTH( NEW.ID ) < 4 THEN
SIGNAL SQLSTATE '12345'
SET MESSAGE_TEXT := 'check constraint on Test.ID failed';
END IF;
END$$
DELIMITER ;
分隔符$$
在插入之前创建触发器“test\u before\u insert`before insert ON`test”`
每行
开始
如果字符长度(NEW.ID)<4,则
信号状态“12345”
设置消息_TEXT:=“检查Test.ID上的约束失败”;
如果结束;
完$$
定界符;
在MySQL 5.5之前,您必须导致错误,例如调用未定义的过程
在这两种情况下,这都会导致隐式事务回滚。
MySQL不允许在过程和触发器中使用ROLLBACK语句本身
如果您不想回滚事务(即使“检查约束”失败,插入/更新也应该通过),您可以使用SET NEW.ID=NULL
覆盖该值,这将把ID设置为字段默认值,但对于ID tho
编辑:
删除了错误的引用
关于:=
运算符:
与=
不同,:=
运算符从不被解释为比较运算符。这意味着您可以在任何有效的SQL语句中(而不仅仅是在SET语句中)使用:=
为变量赋值
关于反勾号标识符引号:
标识符引号字符是反勾号(“`”)
如果启用了ANSI_QUOTES SQL模式,也允许在双引号内引用标识符
正如joanq MariaDB所提到的,现在似乎在其他好处中支持检查约束:
“支持检查约束()。”
自8.0.15版(尚未发布)起支持检查约束
[23 Jan 16:24]Paul Dubois
开发者发布:在8.0.15中修复
之前,MySQL允许有限形式的检查约束语法,
MySQL现在实现了
表和列检查约束,适用于所有存储引擎。
使用CREATETABLE和ALTERTABLE语句定义约束
更新到MySQL 8.0.16以使用检查
:
从MySQL 8.0.16开始,CREATETABLE允许表的核心特性
和列检查约束,用于所有存储引擎。创建表
对于这两个表,允许使用以下检查约束语法
约束和列约束
@thefiloe:Correct,在其他数据库管理系统中,使用正确的CHECK
约束,如果CHECK
计算结果为FALSE
,则插入(或更新)未完成,并导致错误。在MariaDB中修复(参见此答案)。@Jérôme我知道,我有一些(最近的)答案包括在这方面的改进(在MariaDB正确实现检查约束之前,MariaDB和MySQL中都有其他解决此问题的方法)。我不确定的是我是否应该去编辑我所有的旧答案!我想我的评论加上一个最近答案的链接是可以的。或者总比什么都没有好。也许我应该编辑。我不是想给你施加压力让你做任何事。部分同意。考虑到你试图使用它,可以假设你在问这两个问题。事实上,您接受的答案主要是解释为什么它不起作用。您可以对这个功能请求进行投票:但它在十年内没有受到任何关注。您可以在MariaDB中使用检查约束。现在MySQL 8.0.16终于解决了这个问题,是时候无声地承认(!)忽略的内联引用规范了(另一大SQL标准不兼容):……不太简单,至少与CHECK相比:(.Coupla tutes:,呃,这看起来很笨重。我想我宁愿在python中创建一个元组,并在其中检查值,而不是将其放入。快速问题:如果不设置分隔符,为什么这不起作用?但为什么?我的意思是,他们可以删除该命令。保留该命令并删除其功能有什么意义ty?该命令是在Mysql遵循的SQL的ANSI标准中定义的。这实际上没有帮助(Mysql 5.6)它可以防止输入错误类型的数据,但不能防止输入不符合检查
约束条件的数据。在这里,您将发现如何触发错误:这是我始终使用PostgreSQL而不是MySQL的众多原因中的一个。我想知道这是10分钟还是15分钟的开发时间在MySQL中选择抛出