4

我将每一列都设置为,NOT NULL但由于某种原因,我仍然能够NULL在每一列中添加一个值。这是我的表信息(创建语法):

CREATE TABLE `addresses` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `address` varchar(100) NOT NULL,
    `city` varchar(100) NOT NULL,
    `state` varchar(4) NOT NULL,
    `zip` varchar(30) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4545 DEFAULT CHARSET=utf8;

这是一个有效的示例INSERT

INSERT INTO `addresses` (`street`, `city`, `state`, `zip`) VALUES ('', '', '', '');

关于为什么会发生这种情况的任何想法?

4

4 回答 4

15

您正在插入空字符串,而空字符串不是NULL,以检查NULL错误:

INSERT INTO `addresses` (`street`, `city`, `state`, `zip`) VALUES (NULL, NULL, NULL, NULL);

你会看到错误。NOT NULL仅检查不是的值NULL

为了防止空字符串,您必须使用触发器NULL,或者在执行INSERT查询之前对服务器端编程语言进行检查以将空字符串转换为。一个示例触发器INSERT可能类似于:(这只是一个示例)

CREATE TRIGGER avoid_empty
    BEFORE INSERT ON addresses
        FOR EACH ROW
        BEGIN
        IF street = '' THEN SET street = NULL END IF;
END; 
于 2013-09-20T03:29:15.857 回答
2

试试下面

INSERT INTO `addresses` (`street`, `city`, `state`, `zip`) VALUES (NULL, NULL, NULL, NULL);

以上将不起作用

INSERT INTO `addresses` (`street`, `city`, `state`, `zip`) VALUES ('', '', '', '');

上面插入空字符串

空字符串具体表示该值被设置为空;null 表示未设置该值。

为了防止插入空字符串检查这个SO问题

我正在寻找一个约束来防止在 MySQL 中插入空字符串

于 2013-09-20T03:30:00.573 回答
1

''不是NULLNULLNULL

这将失败:

INSERT INTO `addresses` (`street`, `city`, `state`, `zip`) VALUES (NULL, NULL, NULL, NULL);
于 2013-09-20T03:30:52.170 回答
1

如果您可以控制对表的所有插入,那么您可以检查客户端代码中的空字符串,或者如果您希望 MySQL 返回错误,您可以将插入值包装在NULLIF()函数中。假设您使用 php,您的 INSERT 语句可能看起来像

INSERT INTO addresses(city, address, state, zip) 
VALUES (NULLIF(:address, ''), NULLIF(:city, ''), NULLIF(:state, ''), NULLIF(:zip, ''));

防止插入空字符串的另一种方法是使用BEFORE INSERT触发器

CREATE TRIGGER tg_bi_addresses
BEFORE INSERT ON addresses
FOR EACH ROW
  SET NEW.address = 
      CASE WHEN 
       CHAR_LENGTH(NEW.address) = 0 OR
       CHAR_LENGTH(NEW.city)    = 0 OR
       CHAR_LENGTH(NEW.state)   = 0 OR
       CHAR_LENGTH(NEW.zip)     = 0 THEN NULL
       ELSE NEW.address
      END;

这个想法是检测一个空字符串并违反NOT NULL其中一个字段的约束。如果您使用的是 MySQL 5.5 或更高版本,则可以使用SIGNAL.

这是SQLFiddle演示。尝试取消注释最后一个插入语句,触发器将不允许它成功。

于 2013-09-20T03:38:40.597 回答