在 MySQL 中使用检查约束来控制字符串长度
我被一个问题困扰了!
我已经使用 MySQL 设置了第一个检查约束,但不幸的是我遇到了问题。当插入应该无法通过测试的行时,无论如何都会插入该行。
结构:
CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
uname VARCHAR(10) NOT NULL,
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
mail VARCHAR(50) NOT NULL,
PRIMARY KEY (id),
CHECK (LENGTH(fname) > 30)
);
insert 语句:
INSERT INTO user VALUES (null, 'user', 'Fname', 'Lname', '[email protected]');
fname 列中的字符串长度应该太短,但无论如何都插入了。
我很确定我在这里缺少一些基本的东西。
I'm tumbled with a problem!
I've set up my first check constraint using MySQL, but unfortunately I'm having a problem. When inserting a row that should fail the test, the row is inserted anyway.
The structure:
CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
uname VARCHAR(10) NOT NULL,
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
mail VARCHAR(50) NOT NULL,
PRIMARY KEY (id),
CHECK (LENGTH(fname) > 30)
);
The insert statement:
INSERT INTO user VALUES (null, 'user', 'Fname', 'Lname', '[email protected]');
The length of the string in the fname column should be too short, but it's inserted anyway.
I'm pretty sure I'm missing something basic here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
MySQL 不在任何引擎上强制执行 CHECK 约束.
这让我想问,为什么要将
fname
列声明为 VARCHAR(50),但又想强制它的长度只能是 30 个字符?也就是说,唯一的选择是使用触发器:
MySQL doesn't enforce CHECK constraints, on any engine.
Which leads me to ask, why would you declare the
fname
column as VARCHAR(50), but want to enforce that it can only be 30 characters long?That said, the only alternative is to use a trigger:
从 Mysql 8.0.16 开始,可以强制执行检查约束:
当您尝试插入长度不正确的数据时,它会失败:
当您尝试插入长度正确的数据时,它会成功:
但请注意,当 varchar 长度与约束长度匹配时,约束会出现意外行为,并且输入值比预期长:
发生了什么?看起来 MySQL 正在将输入字符串截断为 varchar 长度,然后检查约束,这会导致插入“123456780”,这不是所需的行为。作为一种解决方法,使 varchar 字段至少比约束长度长一个字符,并且检查将按预期进行验证:
然后尝试插入比检查长度长的数据:
As of Mysql 8.0.16, check constraints can be enforced:
When you attempt to insert data of incorrect length, it fails:
When you attempt to insert data of the correct length, it succeeds:
But notice how the constraint has unexpected behavior when the varchar length matches the constraint length, and the input value is longer than expected:
What happened? It looks like MySQL is truncating the input string to the varchar length and then checking the constraint, which results in "123456780" being inserted, which is not the desired behavior. As a workaround, make the varchar field at least one character longer than the constraint length, and the check will validate as expected:
and then try inserting data longer than the check length:
如上所述,你必须使用触发器,MySQL不支持
check
,而且当你的触发器块中有多个语句时,例如声明变量或控制流,你需要以启动它>begin
和end
并将触发器括在两个分隔符
内:注意:如果您使用 MariaDB,请使用
//< /code> 在第一个分隔符之后和第二个分隔符之前,否则,如果您使用 MySQL,请改用
$$
。As mentioned above you have to use a trigger, MySQL doesn't support
check
, also when you have multiple statements inside your trigger block, like declaring variables or control flows, you need to start it withbegin
andend
and enclose your trigger inside twodelimiters
:Note: If you use MariaDB use
//
after the first delimiter and before the second delimiter, otherwise if you use MySQL use$$
instead.