【mysql】mysql8 参考手册--数据类型默认值 支持表达式作为默认值

数据类型规范可以具有显式或隐式默认值。

在数据类型规范子句显式地指示为列的默认值。例子: DEFAULT value

CREATE TABLE t1 (
  i     INT DEFAULT -1,
  c     VARCHAR(10) DEFAULT '',
  price DOUBLE(16,2) DEFAULT 0.00
);

SERIAL DEFAULT VALUE是一个特例。在整数列的定义中,它是的别名NOT NULL AUTO_INCREMENT UNIQUE。

显式DEFAULT子句处理的某些方面取决于版本,如下所述。

从MySQL 8.0.13开始的显式默认值的处理

MySQL 8.0.13之前的显式默认值的处理

隐式违约的处理

从MySQL 8.0.13开始的显式默认值的处理
DEFAULT 子句中 指定的默认值可以是文字常量或表达式。除一个例外,将表达式默认值放在括号内,以将其与文字常量默认值区分开。例子:

CREATE TABLE t1 (
  -- literal defaults
  i INT         DEFAULT 0,
  c VARCHAR(10) DEFAULT '',
  -- expression defaults
  f FLOAT       DEFAULT (RAND() * RAND()),
  b BINARY(16)  DEFAULT (UUID_TO_BIN(UUID())),
  d DATE        DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
  p POINT       DEFAULT (Point(0,0)),
  j JSON        DEFAULT (JSON_ARRAY())
);

唯一的例外是,对于 TIMESTAMP和 DATETIME列,您可以将CURRENT_TIMESTAMP函数指定为默认函数,而不用括号括起来。请参见 第11.2.5节“ TIMESTAMP和DATETIME的自动初始化和更新”。

的BLOB, TEXT, GEOMETRY,和 JSON数据类型可分配仅当值被写入作为表达,即使表情值是一个文字一个缺省值:

这是允许的(将文字默认值指定为表达式):

CREATE TABLE t2 (b BLOB DEFAULT ('abc'));

这会产生错误(字面默认值未指定为表达式):

 CREATE TABLE t2 (b BLOB DEFAULT 'abc');

表达式默认值必须遵守以下规则。如果表达式包含不允许的构造,则会发生错误。

允许使用文字,内置函数(确定性和非确定性)以及运算符。

不允许使用子查询,参数,变量,存储的函数和用户定义的函数。

表达式默认值不能依赖于具有AUTO_INCREMENT属性的列。

一列的表达式默认值可以引用其他表列,但对生成的列或具有表达式默认值的列的引用必须引用表定义中较早出现的列。也就是说,表达式默认值不能包含对生成的列或具有表达式默认值的列的前向引用。

排序约束也适用于对ALTER TABLE表列进行重新排序的用法 。如果结果表的表达式默认值包含对生成的列或具有表达式默认值的列的前向引用,则该语句将失败。

注意
如果表达式默认值的任何组成部分取决于SQL模式,则表的不同用法可能会产生不同的结果,除非在所有用法中SQL模式都相同。

对于CREATE TABLE ... LIKE和 CREATE TABLE ... SELECT,目标表保留原始表中的表达式默认值。

如果表达式默认值引用的是不确定函数,则任何导致对该表达式求值的语句对于基于语句的复制都是不安全的。这包括语句,如 INSERT, UPDATE和 ALTER TABLE。在这种情况下,如果禁用了二进制日志记录,则将正常执行该语句。如果启用了二进制日志记录并将 binlog_format其设置为 STATEMENT,则将记录并执行该语句,但是将警告消息写入错误日志,因为复制从站可能会发散。当 binlog_format设置为 MIXED或时ROW,不执行该语句,并且将错误消息写入错误日志。

mysql> CREATE TABLE t4 (uid BINARY(16) DEFAULT (UUID_TO_BIN(UUID())));
mysql> INSERT INTO t4 () VALUES();
mysql> INSERT INTO t4 () VALUES(DEFAULT);
mysql> SELECT BIN_TO_UUID(uid) AS uid FROM t4;
+--------------------------------------+
| uid |
+--------------------------------------+
| f1109174-94c9-11e8-971d-3bf1095aa633 |
| f110cf9a-94c9-11e8-971d-3bf1095aa633 |
+--------------------------------------+

但是, 仅允许使用具有文字默认值的列,而不能使用具有表达式默认值的列为指定的列指定默认值。 DEFAULT(col_name)

并非所有存储引擎都允许表达式默认值。否则,将 ER_UNSUPPORTED_ACTION_ON_DEFAULT_VAL_GENERATED 发生错误。

如果默认值得出的数据类型不同于声明的列类型,则将根据通常的MySQL类型转换规则对声明的类型进行隐式强制转换。请参见 第12.2节“表达式评估中的类型转换”。

MySQL 8.0.13之前的显式默认值的处理
除了一个例外,DEFAULT子句中指定的默认值 必须是文字常量;它不能是函数或表达式。例如,这意味着您不能将日期列的默认值设置为诸如NOW() 或函数的值CURRENT_DATE。唯一的例外是,对于TIMESTAMP和 DATETIME列,您可以将其指定 CURRENT_TIMESTAMP为默认值。请参见第11.2.5节“ TIMESTAMP和DATETIME的自动初始化和更新”。

在BLOB, TEXT, GEOMETRY,和 JSON数据类型不能指定一个默认值。

如果默认值得出的数据类型不同于声明的列类型,则将根据通常的MySQL类型转换规则对声明的类型进行隐式强制转换。请参见 第12.2节“表达式评估中的类型转换”。

隐式违约的处理
如果数据类型规范不包含任何显式 DEFAULT值,则MySQL将按以下方式确定默认值:

如果该列可以NULL作为值,则使用显式DEFAULT NULL子句定义该列。

如果该列不能NULL作为值,则MySQL定义没有显式DEFAULT子句的列 。例外:如果将该列定义为的一部分,PRIMARY KEY但未明确定义为NOT NULL,则MySQL将其创建为一 NOT NULL列(因为PRIMARY KEYcolumn必须为NOT NULL)。

对于将数据输入到NOT NULL没有显式DEFAULT子句的列中,如果 INSERTor REPLACE语句不包含该列的值,或者一条 UPDATE语句将该列设置为NULL,则MySQL根据当时有效的SQL模式处理该列:

如果启用了严格的SQL模式,则事务表将发生错误,并且该语句将回滚。对于非事务处理表,会发生错误,但是如果此错误发生在多行语句的第二行或后续行中,则会插入前面的行。

如果未启用严格模式,则MySQL将列设置为列数据类型的隐式默认值。

假设表t定义如下:

CREATE TABLE t (i INT NOT NULL);
在这种情况下,i没有明确的默认值,因此在严格模式下,以下每个语句都会产生错误,并且不会插入任何行。当不使用严格模式时,只有第三条语句会产生错误。为前两个语句插入了隐式默认值,但是第三个语句失败,因为DEFAULT(i)无法产生值:

 

 转自http://www.1024sky.cn/blog/article/1134

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值