简体   繁体   English

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

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

I just can't can find an answer for my question.我就是找不到我的问题的答案。 If there is on stack overflow, just post it and I will delete my post.如果有堆栈溢出,只需发布​​它,我将删除我的帖子。

My problem:我的问题:

I want to accept null values in a mysql column, but not by default.我想在 mysql 列中接受null值,但默认情况下不接受。 When I insert a row I should also set a value for that column and that should be required.当我插入一行时,我还应该为该列设置一个值,这应该是必需的。

Right now, in phpmyadmin, if I check Null field (to accept null values), the field Default (default value) will be automatically set with null value.现在,在 phpmyadmin 中,如果我选中Null字段(接受null值),则字段Default (默认值)将自动设置为null值。 That means that I can omit to set a value for that column in an insert query and it will be filled automatically with a null value.这意味着我可以省略在insert查询中为该列设置值,它将自动填充为null值。

When did I say a column should be auto-filled if is not set ?我什么时候说过如果未设置列应自动填充? I said to accept null values, not to be auto-filled.我说接受空值,而不是自动填充。

Do I miss something ?我错过了什么吗?

If a column has the NULL attribute, and you don't specify an explicit DEFAULT attribute, it's as if you defined it with DEFAULT NULL .如果列具有NULL属性,并且您没有指定显式DEFAULT属性,就好像您使用DEFAULT NULL定义了它。 This is specified in the documentation of"Implicit Default Handling" :这在“隐式默认处理”的文档中指定:

If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause.如果列可以将 NULL 作为值,则使用显式 DEFAULT NULL 子句定义该列。

If you want to prevent omitting the column when inserting, I think you can do it by specifying a DEFAULT expression that causes an error.如果您想防止在插入时省略列,我认为您可以通过指定导致错误的DEFAULT表达式来实现。 This requires you to be using at least version 8.0.13 of MySQL, because prior to this the DEFAULT had to be a literal, not an expression.这要求您至少使用 MySQL 8.0.13 版本,因为在此之前DEFAULT必须是文字,而不是表达式。

Quotingthe docs :引用文档

Implicit Default Handling隐式默认处理

If a data type specification includes no explicit DEFAULT value, MySQL determines the default value as follows: If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause.如果数据类型规范不包含显式 DEFAULT 值,MySQL 确定默认值如下: 如果列可以将 NULL 作为值,则使用显式 DEFAULT NULL 子句定义该列。

So if your column is nullable, it always has a default value - whether set explicitly (by DEFAULT ... clause) or implicitly (like described above).因此,如果您的列可以为空,则它始终具有默认值 - 无论是显式设置(通过DEFAULT ...子句)还是隐式设置(如上所述)。

As @Barmar noticed, there's (at least in theory) a way to handle this with providing an always-failing DEFAULT expression (since MySQL 8.0.13 allowing it).正如@Barmar 所注意到的,(至少在理论上)有一种方法可以通过提供始终失败的 DEFAULT 表达式来处理此问题(因为 MySQL 8.0.13 允许它)。

An alternative (available on versions before 8.0.13) is setting up a DEFAULT value that never should be put in your column anyway AND creating an pre-insert trigger checking the inserted value against this special case.另一种方法(在 8.0.13 之前的版本上可用)是设置一个无论如何都不应该放在您的列中的 DEFAULT 值,并创建一个预插入触发器,根据这种特殊情况检查插入的值。

The benefit of this approach is you're more flexible in providing specific errors for that case.这种方法的好处是您可以更灵活地为这种情况提供特定的错误。 The downside is the value you might consider special will end up being actually used by real-world scenarios, causing a really weird bug.缺点是您可能认为特殊的值最终会被实际场景实际使用,从而导致一个非常奇怪的错误。 That's easier to prevent for numbers (0 for unsigned IDs, etc.), but much harder to do with user-created strings and similar entities.这更容易防止数字(0 表示未签名的 ID 等),但对于用户创建的字符串和类似实体则更难。

You can do this by creating a column that accepts a null, and then applying a trigger BEFORE INSERT that checks for null.您可以通过创建一个接受空值的列,然后应用一个触发器 BEFORE INSERT 来检查空值来做到这一点。

For example:例如:

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 ;

Now create a trigger现在创建一个触发器

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 ;

Attemppting to insert a NULL in the nullField column will return an error 45000, but updating a row to contain NULL will succeed.尝试在nullField列中插入 NULL 将返回错误 45000,但将行更新为包含 NULL 会成功。

Tested with MySQL 8 Demo: https://www.db-fiddle.com/f/8eV4VihbeB5woEYwuGMFvK/0使用 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