MySQL8.0学习记录08 - 数据类型默认值

定义默认值的方式

类型默认值可以使用字面量和表达式来定义,表达式需要用括号括起来:

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。

<think>嗯,用户问的是如何在MySQL中为date类型的字段设置默认值。这个问题看起来和之前提到的datetime类型错误有关联,比如引用[2]提到的datetime格式不正确的问题,还有引用[3]和[4]中的Invalid default value错误。首先,我需要确认date类型和datetime类型在默认值设置上的区别。 根据MySQL的文档,date类型存储的是日期,格式为'YYYY-MM-DD',而datetime包含日期和时间。用户可能在设置默认值时使用了不符合格式的值,导致错误。例如,用户可能尝试使用数字或者不正确的字符串格式,比如'20231105',而正确的应该是'2023-11-05'。 接下来,我要考虑设置默认值的正确语法。ALTER TABLE语句加上ALTER COLUMN ... SET DEFAULT,但需要确保默认值的格式正确。例如,设置DEFAULT '2023-01-01'是正确的,而DEFAULT '2023-01'可能有问题,因为缺少日期部分。 另外,用户可能遇到sql_mode的问题,特别是如果sql_mode中包含NO_ZERO_DATE或STRICT_TRANS_TABLES,那么设置'0000-00-00'这样的默认值会被拒绝。这时候可能需要调整sql_mode,或者在允许的情况下使用有效的日期值。 还要注意,从MySQL 5.7开始,默认的sql_mode更加严格,可能会禁止零值日期。引用[5]中提到的调整sql_mode的方法可能适用于这种情况。比如,移除NO_ZERO_IN_DATE和NO_ZERO_DATE,或者使用允许这些值的模式。 另外,用户可能想使用动态的默认值,比如CURRENT_DATE,但MySQL的date类型只支持DEFAULT CURRENT_DATE吗?需要确认这一点,因为datetime和timestamp类型可以使用CURRENT_TIMESTAMP,但date类型是否支持呢?根据我的记忆,MySQL 8.0之后可能支持对date类型使用CURRENT_DATE作为默认值,但旧版本可能不行。需要验证这一点,并告知用户版本差异。 还有可能用户遇到表结构修改时的权限问题,或者表被锁定的情况,但更可能的问题还是格式和sql_mode的限制。因此,总结解决方案应该包括正确的语法、日期格式、sql_mode调整以及版本注意事项。 最后,用户可能需要示例代码来具体操作,比如ALTER TABLE语句和设置sql_mode的命令。同时,提醒用户处理现有数据时可能的影响,比如修改默认值后,新增记录会自动填充默认值,但已有数据不会变化。</think>在MySQL中为$DATE$类型字段设置默认值需要注意语法规范和日期格式合法性,以下是具体实现方法及注意事项: ### 一、基础设置方法 **1. 新建表时设置默认值** ```sql CREATE TABLE example ( id INT PRIMARY KEY, event_date DATE DEFAULT '2023-01-01' -- 正确格式的日期字符串 ); ``` **2. 修改现有表字段** ```sql ALTER TABLE example ALTER COLUMN event_date SET DEFAULT '2023-01-01'; -- 符合ISO 8601标准的日期格式[^2] ``` ### 二、特殊值设置 **1. 使用当前日期作为默认值** ```sql ALTER TABLE example ALTER COLUMN event_date SET DEFAULT (CURRENT_DATE); -- MySQL 8.0+支持函数默认值[^5] ``` **2. 零值处理(需调整sql_mode)** ```sql SET sql_mode = 'ALLOW_INVALID_DATES,NO_ENGINE_SUBSTITUTION'; -- 允许非常规日期值[^4] ALTER TABLE example ALTER COLUMN event_date SET DEFAULT '0000-00-00'; -- 需要配合特定sql_mode使用[^3] ``` ### 三、常见错误解决方案 **1. 日期格式错误** 错误示例:`ALTER COLUMN event_date SET DEFAULT '20231105'` 修正方法:必须使用标准格式`'YYYY-MM-DD'`,如`'2023-11-05'`[^2] **2. 无效默认值错误** 当出现`Invalid default value`时: ```sql -- 查看当前sql_mode SELECT @@sql_mode; -- 移除严格模式限制 SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; -- 移除NO_ZERO_DATE等限制 ``` ### 四、版本差异注意 - MySQL 5.7+默认启用`NO_ZERO_DATE`模式,禁止`0000-00-00`作为默认值 - MySQL 8.0+支持表达式默认值(如`DEFAULT (CURRENT_DATE + INTERVAL 1 DAY)`) - 低版本若需要动态默认日期,需配合触发器实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值