3

我遇到了一个问题!

我已经使用 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 INTO user VALUES (null, 'user', 'Fname', 'Lname', 'mail@me.now');

fname 列中字符串的长度应该太短了,但还是插入了。

我很确定我在这里遗漏了一些基本的东西。

4

2 回答 2

6

MySQL不会在任何引擎上强制执行 CHECK 约束
这让我问,为什么要将fname列声明为 VARCHAR(50),但要强制它只能是 30 个字符长?

也就是说,唯一的选择是使用触发器:

CREATE TRIGGER t1 BEFORE INSERT ON user
 FOR EACH ROW BEGIN

   DECLARE numLength INT;
   SET numLength = (SELECT LENGTH(NEW.fname));

   IF (numLength > 30) THEN
     SET NEW.col = 1/0;
   END IF;

END;
于 2010-06-12T01:28:08.187 回答
0

如上所述,您必须使用触发器,MySQL 不支持check,而且当您在触发器块中有多个语句时,例如声明变量或控制流,您需要使用 and 开始它begin并将end触发器包含在两个内部delimiters

注意:如果您使用 MariaDB ,请//在第一个分隔符之后和第二个分隔符之前使用,否则如果您使用 MySQL,请$$改用。

delimiter //

create trigger `user_insert_trigger` before insert on `user` for each row
begin
    declare maximumFnameLength int unsigned;
    declare fNameLength int unsigned;
    set maximumFnameLength = 30;
    set fNameLength = (select length(new.fNameLength));
    if (fNameLength > maximumFnameLength) then
        signal sqlstate '45000'
            set message_text = 'First name is more than 30 characters long.';
    end if;
end

//

delimiter ;
于 2018-06-02T04:01:27.150 回答