mysql中的check约束不起作用

kgsdhlau  于 2021-06-15  发布在  Mysql
关注(0)|答案(8)|浏览(408)

首先我创建了一个表

CREATE TABLE Customer (
  SD integer CHECK (SD > 0),
  Last_Name varchar (30),
  First_Name varchar(30)
);

然后在表中插入值

INSERT INTO Customer values ('-2','abc','zz');

mysql没有显示错误,它接受了这些值。

slwdgvem

slwdgvem1#

CHECK mysql忽略了约束,如文档中的一个小注解所述: CREATE TABLE 这个 CHECK 子句已解析,但被所有存储引擎忽略。

k7fdbhmy

k7fdbhmy2#

从版本8.0.15开始支持检查约束(尚未发布)
https://bugs.mysql.com/bug.php?id=3464
[1月23日16:24]保罗·杜布瓦
由开发人员发布:在8.0.15中修复。
以前,mysql允许有限形式的check约束语法,但是解析并忽略了它。mysql现在为所有存储引擎实现了表和列检查约束的核心特性。约束是使用CREATETABLE和ALTERTABLE语句定义的。

fnvucqvd

fnvucqvd3#

更新至mysql 8.0.16使用 checks :
从mysql 8.0.16开始,create table允许所有存储引擎使用表和列检查约束的核心特性。对于表约束和列约束,create table允许以下检查约束语法
mysql检查文档

xmd2e60i

xmd2e60i4#

不幸的是,mysql不支持sql检查约束。出于兼容性的考虑,您可以在ddl查询中定义它们,但它们只是被忽略了。
有一个简单的选择
您可以创建 BEFORE INSERT 以及 BEFORE UPDATE 当不满足数据要求时,引发错误或将字段设置为其默认值的触发器。
例如 BEFORE INSERT MySQL5.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 ;

在MySQL5.5之前,您必须导致错误,例如调用未定义的过程。
在这两种情况下,这都会导致隐式事务回滚。mysql不允许在过程和触发器中使用rollback语句本身。
如果您不想回滚事务(insert/update应该通过,即使“check constraint”失败,您也可以使用 SET NEW.ID = NULL 这将把id设置为字段的默认值,对于id tho来说没有意义
编辑:删除了错误的引用。
关于 := 操作员:
不像 = ,的 := 运算符从不被解释为比较运算符。这意味着你可以使用 := 在任何有效的sql语句中(不只是在set语句中)为变量赋值。
https://dev.mysql.com/doc/refman/5.6/en/assignment-operators.html
关于倒勾标识符引号:
标识符引号字符是反勾号(“`”)
如果启用了ansi\ U quotes sql模式,也允许在双引号内引用标识符
http://dev.mysql.com/doc/refman/5.6/en/identifiers.html

elcex8rz

elcex8rz5#

mysql 8.0.16是第一个支持检查约束的版本。
阅读https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html
如果您使用mysql 8.0.15或更早版本,mysql参考手册会说:
这个 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 ;

希望有帮助。

mccptt67

mccptt676#

正如joanq mariadb所提到的,现在似乎在其他好处中支持检查约束:
“支持检查约束(mdev-7563)。”
https://mariadb.com/kb/en/mariadb/mariadb-1021-release-notes/

20jt8wwn

20jt8wwn7#

尝试 set sql_mode = 'STRICT_TRANS_TABLES' 或者 SET sql_mode='STRICT_ALL_TABLES'

nbysray5

nbysray58#

这个 CHECK 约束似乎没有在mysql中实现。
请参阅此错误报告:https://bugs.mysql.com/bug.php?id=3464

相关问题