文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


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

14.24.3 表达式处理

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

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

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

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

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

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

插入到数值列的操作受 SQL 模式的影响,该模式由 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.24.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 错误情况;未插入任何行。