在 MySql 列中接受空值但默认情况下不接受
Accept null values but not by default in a MySql column
我就是找不到问题的答案。如果堆栈溢出,只需 post 它,我将删除我的 post.
我的问题:
我想在 mysql 列中接受 null
值,但默认情况下不接受。当我插入一行时,我还应该为该列设置一个值,这应该是必需的。
现在,在 phpmyadmin 中,如果我选中 Null 字段(接受 null
值),字段 Default (默认值)将自动设置为 null
值。这意味着我可以省略在 insert
查询中为该列设置值,它将自动填充 null
值。
我什么时候说过如果没有设置列应该自动填充?我说接受空值,不是自动填充
我错过了什么吗?
引用 the 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.
因此,如果您的列可以为 null,它 总是 有一个默认值 - 无论是显式设置(通过 DEFAULT ...
子句)还是隐式设置(如上所述)。
正如@Barmar 所注意到的,(至少在理论上)有一种方法可以通过提供始终失败的 DEFAULT 表达式来处理此问题(因为 MySQL 8.0.13 允许它)。
另一种方法(在 8.0.13 之前的版本上可用)是设置一个无论如何都不应该放在您的列中的默认值,并创建一个预插入触发器,根据这种特殊情况检查插入的值。
这种方法的好处是您可以更灵活地针对该情况提供特定错误。缺点是您可能认为特殊的值最终会被现实世界的场景实际使用,从而导致一个非常奇怪的错误。这对于数字来说更容易预防(0 代表未签名的 ID 等),但对于用户创建的字符串和类似实体来说更难预防。
如果列具有 NULL
属性,而您没有指定明确的 DEFAULT
属性,就好像您使用 DEFAULT NULL
定义它一样。这在 "Implicit Default Handling":
的文档中指定
If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause.
如果你想防止在插入时遗漏列,我想你可以通过指定一个导致错误的DEFAULT
表达式来实现。这要求您至少使用 MySQL 的 8.0.13 版本,因为在此之前 DEFAULT
必须是文字,而不是表达式。
您可以通过创建一个接受 null 的列,然后应用检查 null 的 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 将 return 错误 45000,但更新包含 NULL 的行将会成功。
测试 MySQL 8
演示:https://www.db-fiddle.com/f/8eV4VihbeB5woEYwuGMFvK/0
我就是找不到问题的答案。如果堆栈溢出,只需 post 它,我将删除我的 post.
我的问题:
我想在 mysql 列中接受 null
值,但默认情况下不接受。当我插入一行时,我还应该为该列设置一个值,这应该是必需的。
现在,在 phpmyadmin 中,如果我选中 Null 字段(接受 null
值),字段 Default (默认值)将自动设置为 null
值。这意味着我可以省略在 insert
查询中为该列设置值,它将自动填充 null
值。
我什么时候说过如果没有设置列应该自动填充?我说接受空值,不是自动填充
我错过了什么吗?
引用 the 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.
因此,如果您的列可以为 null,它 总是 有一个默认值 - 无论是显式设置(通过 DEFAULT ...
子句)还是隐式设置(如上所述)。
正如@Barmar 所注意到的,(至少在理论上)有一种方法可以通过提供始终失败的 DEFAULT 表达式来处理此问题(因为 MySQL 8.0.13 允许它)。
另一种方法(在 8.0.13 之前的版本上可用)是设置一个无论如何都不应该放在您的列中的默认值,并创建一个预插入触发器,根据这种特殊情况检查插入的值。
这种方法的好处是您可以更灵活地针对该情况提供特定错误。缺点是您可能认为特殊的值最终会被现实世界的场景实际使用,从而导致一个非常奇怪的错误。这对于数字来说更容易预防(0 代表未签名的 ID 等),但对于用户创建的字符串和类似实体来说更难预防。
如果列具有 NULL
属性,而您没有指定明确的 DEFAULT
属性,就好像您使用 DEFAULT NULL
定义它一样。这在 "Implicit Default Handling":
If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause.
如果你想防止在插入时遗漏列,我想你可以通过指定一个导致错误的DEFAULT
表达式来实现。这要求您至少使用 MySQL 的 8.0.13 版本,因为在此之前 DEFAULT
必须是文字,而不是表达式。
您可以通过创建一个接受 null 的列,然后应用检查 null 的 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 将 return 错误 45000,但更新包含 NULL 的行将会成功。
测试 MySQL 8 演示:https://www.db-fiddle.com/f/8eV4VihbeB5woEYwuGMFvK/0