MySQL中的CHECK约束不起作用

7ivaypg9  于 2022-12-26  发布在  Mysql
关注(0)|答案(8)|浏览(299)

首先,我创建了一个表,如

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

然后在表中插入值

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

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

mpbci0fu

mpbci0fu1#

不幸的是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设置为字段的默认值,但对于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

w3nuxt5m

w3nuxt5m2#

MySQL忽略了CHECK约束,如文档中的一个小注解所述:* * 一个
所有存储引擎都会分析CHECK子句,但会将其忽略。

bz4sfanl

bz4sfanl3#

CHECK约束似乎没有在MySQL中实现。
查看此错误报告:https://bugs.mysql.com/bug.php?id=3464

t5zmwmid

t5zmwmid4#

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

cvxl0en2

cvxl0en25#

自版本8.0.15(尚未发布)起支持检查约束
https://bugs.mysql.com/bug.php?id=3464
[23 1月16日:24]保罗·迪布瓦
发布者:开发者:已在8.0.15中修复。
以前,MySQL允许有限形式的CHECK约束条件语法,但会对其进行分析并将其忽略。现在,MySQL为所有存储引擎实现了表和列CHECK约束条件的核心功能。约束条件是使用CREATE TABLE和ALTER TABLE语句定义的。

mrzz3bfm

mrzz3bfm6#

更新到MySQL 8.0.16以使用checks
从MySQL 8.0.16开始,CREATE TABLE允许所有存储引擎使用表和列CHECK约束的核心功能。CREATE TABLE允许表约束和列约束使用以下CHECK约束语法
MySQL Checks Documentation

oxcyiej7

oxcyiej77#

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

omvjsjqw

omvjsjqw8#

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 ;

相关问题