数据类型规范可以有显式或隐式的默认值。
数据类型规范中的DEFAULT值子句显式指示列的默认值。示例:
SERIAL DEFAULT VALUE是一种特殊情况。在整数列的定义中,它是NOT NULL AUTO_INCREMENT UNIQUE的别名。
处理显式DEFAULT子句,某些方面依赖于特定版本,如下所述。
●MySQL 8.0.13处理显式默认值
●MySQL8.0.13之前处理显式默认值
●处理隐式默认值
MySQL 8.0.13处理显式默认值
DEFAULT子句中指定的默认值可以是字面常量或表达式。有一个例外,将表达式默认值括在括号内,以区别于字面常量默认值。示例:
例外情况是,对于TIMESTAMP和DATETIME列,可以指定CURRENT_TIMESTAMP函数作为默认值,而不需要用括号括起来。
只有用表达式才能给BLOB、TEXT、GEOMETRY和JSON数据类型分配默认值,即使表达式值是字面量:
●这种方式可行(字面量默认值指定为表达式):
●这种方式将产生错误(字面量默认值未指定为表达式):
表达式默认值必须符合以下规则。如果表达式包含不允许的结构,则会发生错误。
●允许使用字面量、内置函数(确定性函数和非确定性函数)以及运算符。
●不允许使用子查询、参数、变量、存储过程和用户定义函数。
●表达式默认值不能依赖于具有AUTO_INCREMENT属性的列。
●列的表达式默认值可以引用其他列,但是表达式默认值引用的生成列或具有表达式默认值的列必须是前向引用。
这个顺序约束也适用于使用ALTER TABLE语句重新排序表的列。如果结果表的表达式默认值包含对生成的列或具有表达式默认值的列的后向引用,则该语句将失败。
对于CREATE TABLE ... LIKE 和 CREATE TABLE ... SELECT语句,则目标表将保留原始表中的表达式默认值。
如果表达式默认值引用不确定函数,则导致表达式计算的任何语句对于基于语句的复制来说都是不安全的。这包括INSERT和UPDATE等语句。在这种情况下,如果禁用了二进制日志记录,则该语句将正常执行。如果启用了二进制日志记录,并且binlog_format设置为STATEMENT,则会记录并执行该语句,但会在错误日志中写入一条警告消息,因为复制从属服务器可能会发生分歧。当binlog_format设置为MIXED或ROW时,语句将正常执行。
插入新行时,可以通过省略列名或将列指定为DEFAULT(就像对于具有字面量默认值的列一样)来插入具有表达式默认值的列:
但是,仅允许对具有字面量默认值的列使用DEFAULT(col_name)指定列为默认值,而不允许对具有表达式默认值的列使用。
并非所有存储引擎都允许表达式默认值。对于不支持的存储引擎,会引发 ER_UNSUPPORTED_ACTION_ON_DEFAULT_VAL_GENERATED 错误。
如果默认值的计算结果与声明的列类型不同,则会根据通常的MySQL类型转换规则隐式转换为声明的类型。
MySQL8.0.13之前处理显式默认值
有一个不同情况,DEFAULT子句中指定的默认值必须是字面常量;它不能是函数或表达式。这意味着,不能将日期列的默认值设置为函数的值,例如NOW()或CURRENT_DATE。例外情况是,对于TIMESTAMP和DATETIME列,可以将CURRENT_TIMESTAMP指定为默认值。
无法为BLOB、TEXT、GEOMETRY和JSON数据类型分配默认值。
如果默认值的计算结果与声明的列类型不同,则会根据常规的MySQL类型转换规则隐式转换为声明的类型。
处理隐式默认值
如果一个数据类型规范中没有显式的默认值,那么MySQL会按如下方式确定默认值:
如果列可以接受NULL值,则使用显式的DEFAULT NULL子句定义该列。
如果列不能接受NULL值,MySQL将不使用显式DEFAULT子句定义该列。
对于没有显式DEFAULT子句的NOT NULL列的数据输入,如果INSERT或REPLACE语句不包含该列的值,或者UPDATE语句将该列设置为NULL,则MySQL会根据当时有效的SQL模式处理该列:
●如果启用了严格SQL模式,事务表将出错,语句将回滚。对于非事务表,会引发错误,但如果多行语句的第二行或后续行发生这种情况,则前面的行将被插入。
●如果未启用严格模式,MySQL会将列设置为列数据类型的隐式默认值。
假设表t的定义如下:
在本例中,i没有显式默认值,因此在严格模式下,下面的每个语句都会产生一个错误,并且不会插入任何行。不使用严格模式时,只有第三条语句产生错误;前两条语句插入隐式默认值,但第三条语句失败,因为DEFAULT(i)无法生成值:
对于给定的表,SHOW CREATE TABLE语句显示哪些列具有显式DEFAULT子句。
隐式默认值定义如下:
●对于数值类型,默认值为0,但是有个例外,对于使用AUTO_INCREMENT属性声明的整数或浮点类型,默认值是序列中的下一个值。
●对于TIMESTAMP以外的日期和时间类型,默认值是该类型的适当的"零"值。如果启用了explicit_defaults_for_timestamp系统变量,则TIMESTAMP类型也是如此。否则,对于表中的第一个TIMESTAMP列,默认值为当前日期和时间。
●对于ENUM以外的字符串类型,默认值为空字符串。对于ENUM,默认值是第一个枚举值。
官方文档:
https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html
阅读 9
原文:https://blog.51cto.com/15023289/2560949