137

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.

4

8 回答 8

152

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

阅读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 ;

希望有帮助。

于 2010-01-22T07:11:03.147 回答
76

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

有一个简单的替代方案

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

BEFORE INSERTMySQL 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 ;  

在 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

于 2013-01-09T23:00:58.730 回答
53

CHECKMySQL 忽略了约束,如文档中的一条微不足道的注释中所述:CREATE TABLE

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

于 2013-01-09T22:31:15.147 回答
16

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

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

于 2010-01-22T06:37:29.243 回答
9

正如 joanq MariaDB 所提到的,现在似乎支持 CHECK 约束以及其他好东西:

“支持检查约束 ( MDEV-7563 )。”

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

于 2017-06-02T16:17:37.840 回答
1

更新到 MySQL 8.0.16 以使用checks

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

MySQL 检查文档

于 2019-02-04T19:50:19.420 回答
1

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

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

[1月23日16:24]保罗杜布瓦

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

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

于 2019-01-30T11:16:15.663 回答
-2

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

于 2012-01-29T05:02:48.390 回答