MySQL 中的 CHECK 约束不起作用

发布于 2024-08-18 23:14:21 字数 281 浏览 6 评论 0原文

首先,我创建了一个类似的表

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

,然后在该表中插入了值,

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

删除会话 2024-08-25 23:14:21

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 ;

MySQL 8.0.16 is the first version that supports CHECK constraints.

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

If you use MySQL 8.0.15 or earlier, the MySQL Reference Manual says:

The CHECK clause is parsed but ignored by all storage engines.

Try a trigger...

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 ;
爱她像谁 2024-08-25 23:14:21

不幸的是 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

Unfortunately MySQL does not support SQL check constraints. You can define them in your DDL query for compatibility reasons but they are just ignored.

There is a simple alternative

You can create BEFORE INSERT and BEFORE UPDATE triggers which either cause an error or set the field to its default value when the requirements of the data are not met.

Example for BEFORE INSERT working after 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 ;  

Prior to MySQL 5.5 you had to cause an error, e.g. call a undefined procedure.

In both cases this causes an implicit transaction rollback.
MySQL does not allow the ROLLBACK statement itself within procedures and triggers.

If you don't want to rollback the transaction ( INSERT / UPDATE should pass even with a failed "check constraint" you can overwrite the value using SET NEW.ID = NULL which will set the id to the fields default value, doesn't really make sense for an id tho

Edit:
Removed the stray quote.

Concerning the := operator:

Unlike =, the := operator is never interpreted as a comparison operator. This means you can use := in any valid SQL statement (not just in SET statements) to assign a value to a variable.

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

Concerning backtick identifier quotes:

The identifier quote character is the backtick (“`”)

If the ANSI_QUOTES SQL mode is enabled, it is also permissible to quote identifiers within double quotation marks

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

阳光①夏 2024-08-25 23:14:21

MySQL 会忽略 CHECK 约束,如文档中的小注释中所述:创建表

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

CHECK constraints are ignored by MySQL as explained in a miniscule comment in the docs: CREATE TABLE

The CHECK clause is parsed but ignored by all storage engines.

jJeQQOZ5 2024-08-25 23:14:21

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

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

The CHECK constraint doesn't seem to be implemented in MySQL.

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

蓝咒 2024-08-25 23:14:21

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

“支持 CHECK CONSTRAINT (MDEV- 7563)。”

https://mariadb.com/kb/en/mariadb/mariadb- 1021-发行说明/

As mentioned by joanq MariaDB now seems to support CHECK constraints among other goodies:

"Support for CHECK CONSTRAINT (MDEV-7563)."

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

掀纱窥君容 2024-08-25 23:14:21

从版本 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 语句定义的。

Check constraints are supported as of version 8.0.15 (yet to be released)

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

[23 Jan 16:24] Paul Dubois

Posted by developer: Fixed in 8.0.15.

Previously, MySQL permitted a limited form of CHECK constraint syntax,
but parsed and ignored it. MySQL now implements the core features of
table and column CHECK constraints, for all storage engines.
Constraints are defined using CREATE TABLE and ALTER TABLE statements.

懒猫 2024-08-25 23:14:21

更新到 MySQL 8.0.16 以使用检查

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

MySQL 检查文档

Update to MySQL 8.0.16 to use checks:

As of MySQL 8.0.16, CREATE TABLE permits the core features of table
and column CHECK constraints, for all storage engines. CREATE TABLE
permits the following CHECK constraint syntax, for both table
constraints and column constraints

MySQL Checks Documentation

夜血缘 2024-08-25 23:14:21

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

try with set sql_mode = 'STRICT_TRANS_TABLES' OR SET sql_mode='STRICT_ALL_TABLES'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文