MySQL中的CHECK约束不起作用

时间:2010-01-22 06:33:33

标签: 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没有显示错误,它接受了值。

8 个答案:

答案 0 :(得分:126)

MySQL 8.0.16是第一个支持CHECK约束的版本。

阅读https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html

如果您使用的是MySQL 8.0.15或更早版本,MySQL Reference Manual会说:

  

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 ;

希望有所帮助。

答案 1 :(得分:71)

不幸的是,MySQL不支持SQL检查约束。您可以出于兼容性原因在DDL查询中定义它们,但它们只是被忽略。

有一个简单的替代方案

您可以创建导致错误的BEFORE INSERTBEFORE UPDATE触发器,或者在不满足数据要求时将字段设置为默认值。

在MySQL 5.5

之后BEFORE INSERT工作的示例
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 ;  

在MySQL 5.5之前,您必须导致错误,例如调用一个未定义的程序。

在这两种情况下都会导致隐式事务回滚。 MySQL不允许在程序和触发器中使用ROLLBACK语句。

如果您不想回滚事务(INSERT / UPDATE应该通过失败的“检查约束”,您可以使用SET NEW.ID = NULL覆盖该值,这将id设置为字段默认值,不对于身份来说真的很有意义

修改 删除了流浪的报价。

关于:=运营商:

  

=不同,:=运算符永远不会被解释为比较运算符。这意味着您可以在任何有效的SQL语句中使用:=(而不仅仅是在SET语句中)为变量赋值。

https://dev.mysql.com/doc/refman/5.6/en/assignment-operators.html

关于反引号标识符引号:

  

标识符引号字符是反引号(“`”)

     

如果启用了ANSI_QUOTES SQL模式,也允许在双引号内引用标识符

http://dev.mysql.com/doc/refman/5.6/en/identifiers.html

答案 2 :(得分:50)

MySQL会忽略

CHECK个约束,正如文档中的一个微不足道的评论所解释的那样: CREATE TABLE

  

CHECK子句被解析但被所有存储引擎忽略。

答案 3 :(得分:15)

CHECK约束似乎没有在MySQL中实现。

请参阅此错误报告:https://bugs.mysql.com/bug.php?id=3464

答案 4 :(得分:8)

正如joanq所说,MariaDB现在似乎支持其他好东西中的CHECK限制:

&#34;支持CHECK CONSTRAINT(MDEV-7563)。&#34;

https://mariadb.com/kb/en/mariadb/mariadb-1021-release-notes/

答案 5 :(得分:1)

从8.0.15版本开始支持检查约束(尚未发布)

https://bugs.mysql.com/bug.php?id=3464

  

[1月23日16:24]保罗·杜波依斯(Paul Dubois)

     

开发者发布:已在8.0.15中修复。

     

以前,MySQL允许使用有限形式的CHECK约束语法,   但解析并忽略了它。 MySQL现在实现了以下功能   所有存储引擎的表和列CHECK约束。   约束是使用CREATE TABLE和ALTER TABLE语句定义的。

答案 6 :(得分:1)

更新到MySQL 8.0.16以使用checks

  

从MySQL 8.0.16开始,CREATE TABLE允许表的核心功能   和列CHECK约束,适用于所有存储引擎。创建表   对于两个表都允许使用以下CHECK约束语法   约束和列约束

MySQL Checks Documentation

答案 7 :(得分:-1)

尝试使用set sql_mode = 'STRICT_TRANS_TABLES'SET sql_mode='STRICT_ALL_TABLES'