定义默认值的方式
类型默认值可以使用字面量和表达式来定义,表达式需要用括号括起来:
create table t_text(
a int default 0,
b varchar(64) DEFAULT (UUID()),
c DATE DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
d float default (RAND() * RAND()),
e DATETIME default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
f BLOB default ('hello')
);
insert into t_text() values();
SELECT * FROM t_text;
a|b |c |d |e |f |
-+------------------------------------+----------+--------+-------------------+-----+
0|66f735d9-c17c-11ec-89b9-0242ac120003|2023-04-21|0.496599|2022-04-21 14:07:38|hello|
日期类型有个可以自动更新的属性 ON UPDATE,在更新其他列值的时候,该列自动更新
update t_text set a = 1 where a=0;
SELECT * FROM t_text;
可以看到时间e更新了:
a|b |c |d |e |f |
-+------------------------------------+----------+--------+-------------------+-----+
1|66f735d9-c17c-11ec-89b9-0242ac120003|2023-04-21|0.496599|2022-04-21 14:08:23|hello|
表达式的要求
- 可以使用字面量、内置函数以及操作符
- 不能使用子查询、参数、变量、存储函数
- 列不能拥有AUTO_INCREMENT属性
- 表达式可以引用其他列,但是如果引用生成列或者带有表达式默认值的列,被引用的列要先定义
一般列表达式引用其他列的顺序无限制:
create table t_text(
a int default 0,
b int DEFAULT (a + 2),
c varchar(10) default(concat(d,'_c')),
d varchar(10) default 'd'
);
insert into t_text() values();
/*
a|b|c |d|
0|2|d_c|d|
*/
insert into t_text(a,d) values(100,'hello');
/*
a |b |c |d |
100|102|hello_c|hello|
*/
如下,d的默认值是表达式,c在d前面定义,c的表达式引用d是不合法的:
create table t_text(
a int default (0),
b int default (a+10), --正确
c varchar(10) default(concat(d,'_c')), -- 错误
d varchar(10) default ('d')
);
另外:BLOB, TEXT, GEOMETRY和 JSON只能拥有带表达式的默认值
隐式默认处理
如果未显式指定DEFAULT,而且类型可以为NULL,那么MySQL也会加上DEFAULT NULL。
对于定义NOT NULL的列,如果在INSERT、REPLACE、UPDATE语句中,给该列赋值为NULL,那么根据SQL模式进行相应的处理:
- 如果是严格模式,会报错,并回滚事务
- 如果是非严格模式,那么根据数据类型来决定其默认值:
create table t_text(
a int not null,
b varchar(10) not null,
c decimal(4,2) not null,
d datetime not null,
e BLOB not null,
f JSON not null
);
SET sql_mode = '';
insert into t_text() values();
结果如下:
a|b|c |d |e|f |
-+-+----+-------------------+-+----+
0| |0.00|0000-00-00 00:00:00| |null|
这里注意f 并不是MySQL的NULL类型,而是JSON的NULL。