【问题标题】:Accept null values but not by default in a MySql column在 MySql 列中接受空值,但默认情况下不接受
【发布时间】:2021-09-03 14:24:42
【问题描述】:

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

我的问题:

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

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

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

我错过了什么吗?

【问题讨论】:

  • 默认值应该是什么?
  • @SamiKuhmonen 没有价值。 insert 查询应该需要它。
  • 所以你希望这个 not 在插入时接受空值,但在更新时接受空值?
  • @raina77ow 他想要求INSERT指定列的值,不允许它被默认。
  • @Barmar 完全正确。

标签: mysql null


【解决方案1】:

引用the docs:

隐式默认处理

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

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

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

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

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

【讨论】:

    【解决方案2】:

    如果一列具有NULL 属性,并且您没有指定显式DEFAULT 属性,就好像您使用DEFAULT NULL 定义了它。这是在"Implicit Default Handling"的文档中指定的:

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

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

    【讨论】:

    • 我想知道是否可以通过设置一个从不使用的默认值来克服 8.0.13 的限制(数字更容易,文本更难),然后有一个插入/更新触发器丢弃它价值。
    • “指定一个导致错误的 DEFAULT 表达式”是一种好方法吗?不是坏习惯吗?
    • @Andrei 如果INSERT 未指定列,您希望尝试得到错误,不是吗?数据库对此没有任何“良好做法”。
    • @raina77ow 我不知道触发器如何判断INSERT 查询是否具有列的显式值。
    【解决方案3】:

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

    例如:

    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 测试 演示:https://www.db-fiddle.com/f/8eV4VihbeB5woEYwuGMFvK/0

    【讨论】:

    • 但他们不想阻止插入空值,只是防止在插入时未指定列名
    猜你喜欢
    • 2020-10-11
    • 2011-05-31
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 2020-05-16
    • 2019-10-07
    相关资源
    最近更新 更多