文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  表达式处理

14.25.3 表达式处理

对于精确数学,只要有可能,就会按原样使用精确值数字。例如,比较中的数字将完全按照给定的值使用,而不会改变值。在严格 SQL 模式下,对于 INSERT 到具有精确数据类型的列(DECIMAL 或整数),如果数字在其列范围内,则会以其精确值插入。检索时,该值应与插入的值相同。(如果未启用严格 SQL 模式,则允许对 INSERT 进行截断。)

数值表达式的处理方式取决于表达式包含的值的类型

  • 如果存在任何近似值,则表达式为近似值,并使用浮点算法进行计算。

  • 如果不存在任何近似值,则表达式仅包含精确值。如果任何精确值包含小数部分(小数点后的值),则使用 DECIMAL 精确算法对表达式进行计算,精度为 65 位。术语“精确”受限于二进制可以表示的内容。例如,1.0/3.0 可以用十进制表示法近似为 .333...,但不能写成精确的数字,因此 (1.0/3.0)*3.0 的计算结果不完全等于 1.0

  • 否则,表达式仅包含整数值。该表达式是精确的,使用整数算法进行计算,精度与 BIGINT(64 位)相同。

如果数值表达式包含任何字符串,则它们将转换为双精度浮点值,并且表达式为近似值。

插入到数值列的操作受 SQL 模式的 ảnh hưởng,该模式由 sql_mode 系统变量控制。(请参阅 第 7.1.11 节“服务器 SQL 模式”。)以下讨论提到了严格模式(由 STRICT_ALL_TABLESSTRICT_TRANS_TABLES 模式值选择)和 ERROR_FOR_DIVISION_BY_ZERO。要启用所有限制,您只需使用 TRADITIONAL 模式,其中包括严格模式值和 ERROR_FOR_DIVISION_BY_ZERO

SET sql_mode='TRADITIONAL';

如果将数字插入到精确类型列(DECIMAL 或整数),则如果该数字在其列范围和精度内,则将以其精确值插入。

如果该值的小数部分位数过多,则会进行舍入并生成注释。舍入操作的执行方式如 第 14.25.4 节“舍入行为” 中所述。即使在严格模式下,由于小数部分舍入而导致的截断也不是错误。

如果该值的整数部分位数过多,则表示该值过大(超出范围),将按如下方式处理

  • 如果未启用严格模式,则该值将截断为最接近的合法值,并生成警告。

  • 如果启用了严格模式,则会发生溢出错误。

不会检测到下溢,因此未定义下溢处理。

对于将字符串插入到数值列的操作,如果字符串包含非数字内容,则从字符串到数字的转换将按如下方式处理

  • 不以数字开头的字符串不能用作数字,在严格模式下会产生错误,否则会产生警告。这包括空字符串。

  • 以数字开头的字符串可以转换,但尾随的非数字部分将被截断。如果截断的部分包含空格以外的任何内容,则在严格模式下会产生错误,否则会产生警告。

默认情况下,除以零会产生 NULL 的结果,并且不会发出警告。通过适当地设置 SQL 模式,可以限制除以零的操作。

启用 ERROR_FOR_DIVISION_BY_ZERO SQL 模式后,MySQL 对除以零的处理方式有所不同

  • 如果未启用严格模式,则会发出警告。

  • 如果启用了严格模式,则禁止插入和更新操作中出现除以零的情况,并且会发生错误。

换句话说,涉及执行除以零操作的表达式的插入和更新操作可以被视为错误,但这需要 ERROR_FOR_DIVISION_BY_ZERO 以及严格模式。

假设我们有以下语句

INSERT INTO t SET i = 1/0;

对于严格模式和 ERROR_FOR_DIVISION_BY_ZERO 模式的组合,将会发生以下情况。

sql_mode 结果
'' (默认值) 无警告,无错误;i 设置为 NULL
严格 无警告,无错误;i 设置为 NULL
ERROR_FOR_DIVISION_BY_ZERO 警告,无错误;i 设置为 NULL
严格,ERROR_FOR_DIVISION_BY_ZERO 错误情况;未插入任何行。