MYSQL在非空默认列中插入空值

4

我很好奇为什么有些非空列已经设置了默认值,但在插入SQL脚本时,却会抛出错误。

以下是样例表格:

drop table if exists `delivery`;
create table `delivery`(
    `price` BIGINT not null default 0,
    `created_time` TIMESTAMP(6) not null default CURRENT_TIMESTAMP (6)
) ENGINE=INNODB DEFAULT CHARSET=UTF8MB4
;

假设执行以下三条语句,只有第二条语句不会抛出错误

insert into `delivery` (`price`,`created_time`) values (null, null);
insert into `delivery` (`price`,`created_time`) values (1, null);
insert into `delivery` (`price`,`created_time`) values (null, now());

有没有办法在 bigint 数据类型列中插入 null 并使其成功执行?有关逻辑的任何想法?

这些行为受SQL_MODE变量的影响很大。 - Álvaro González
1个回答

2

由于列上有 NOT NULL 约束,因此您无法插入空值。

第一条和第三条语句会抛出错误,因为您试图将空值插入到 price 和/或 created_time 列中,这显然不满足约束条件。

如果您确实想允许空值,则应删除列上的 NOT NULL 约束。

或者,您可以按照下面所示的方式成功运行 SQL 语句:

insert into `delivery` () values ();
insert into `delivery` (`price`) values (1);
insert into `delivery` (`created_time`) values (now());

select * from `delivery`;

结果:

price  created_time              
-----  --------------------------
    0  2020-04-16 09:48:23.505147
    1  2020-04-16 09:48:25.549202
    0  2020-04-16 09:48:26.0     

编辑:

在MySQL 5.7中,第二个查询实际上是成功的;它会默默地忽略明确的空值并使用默认值。

似乎这个行为在MySQL 8.x中得到了修复,因为现在它会失败(应该如此)。


第二个语句将created_time设置为null,而created_time又是NOT NULL,为什么它能够正常工作? - kmoser
@kmoser 第二个失败了: 错误: 列 'created_time' 不能为 null - SQL状态: 23000 - 错误代码: 1048。请参见示例 https://www.db-fiddle.com/f/jSe88MiqpD2D9haN9sgDDw/0 - The Impaler
@TheImpaler 我能够执行第二个语句,但它是本地设置的数据库。 - oka96
@TheImpaler 很有趣,我在MySQL 5.7上测试了第二个查询,它可以工作。 - kmoser
3
时间戳的特定“空值行为”由explicit_defaults_for_timestamp和严格模式配置决定。请查看它们。另外,您可以尝试使用时间戳和空值进行其他有趣的操作:当您插入一行或两行时,其行为可能会有所不同。对于所有其他数据类型,行为与“The Impaler”所描述的相同。 - Solarflare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接