繁体   English   中英

在 MySql 列中接受空值,但默认情况下不接受

[英]Accept null values but not by default in a MySql column

我就是找不到我的问题的答案。 如果有堆栈溢出,只需发布​​它,我将删除我的帖子。

我的问题:

我想在 mysql 列中接受null值,但默认情况下不接受。 当我插入一行时,我还应该为该列设置一个值,这应该是必需的。

现在,在 phpmyadmin 中,如果我选中Null字段(接受null值),则字段Default (默认值)将自动设置为null值。 这意味着我可以省略在insert查询中为该列设置值,它将自动填充为null值。

我什么时候说过如果未设置列应自动填充? 我说接受空值,而不是自动填充。

我错过了什么吗?

如果列具有NULL属性,并且您没有指定显式DEFAULT属性,就好像您使用DEFAULT NULL定义了它。 这在“隐式默认处理”的文档中指定:

如果列可以将 NULL 作为值,则使用显式 DEFAULT NULL 子句定义该列。

如果您想防止在插入时省略列,我认为您可以通过指定导致错误的DEFAULT表达式来实现。 这要求您至少使用 MySQL 8.0.13 版本,因为在此之前DEFAULT必须是文字,而不是表达式。

引用文档

隐式默认处理

如果数据类型规范不包含显式 DEFAULT 值,MySQL 确定默认值如下: 如果列可以将 NULL 作为值,则使用显式 DEFAULT NULL 子句定义该列。

因此,如果您的列可以为空,则它始终具有默认值 - 无论是显式设置(通过DEFAULT ...子句)还是隐式设置(如上所述)。

正如@Barmar 所注意到的,(至少在理论上)有一种方法可以通过提供始终失败的 DEFAULT 表达式来处理此问题(因为 MySQL 8.0.13 允许它)。

另一种方法(在 8.0.13 之前的版本上可用)是设置一个无论如何都不应该放在您的列中的 DEFAULT 值,并创建一个预插入触发器,根据这种特殊情况检查插入的值。

这种方法的好处是您可以更灵活地为这种情况提供特定的错误。 缺点是您可能认为特殊的值最终会被实际场景实际使用,从而导致一个非常奇怪的错误。 这更容易防止数字(0 表示未签名的 ID 等),但对于用户创建的字符串和类似实体则更难。

您可以通过创建一个接受空值的列,然后应用一个触发器 BEFORE INSERT 来检查空值来做到这一点。

例如:

CREATE TABLE `testNulls` (
  `id` int NOT NULL AUTO_INCREMENT,
  `nullField` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ;

现在创建一个触发器

DELIMITER $$
CREATE TRIGGER `testNulls_BEFORE_INSERT` BEFORE INSERT ON `testNulls` FOR EACH ROW BEGIN
  if (new.nullField is null) then  
      signal sqlstate '45000' set message_text = 'Cannot insert NULL in nullField';
      END IF;
END$$
DELIMITER ;

尝试在nullField列中插入 NULL 将返回错误 45000,但将行更新为包含 NULL 会成功。

使用 MySQL 8 Demo 测试: https : //www.db-fiddle.com/f/8eV4VihbeB5woEYwuGMFvK/0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM