12.25.3 Expression Handling表达式处理

With precision math, exact-value numbers are used as given whenever possible. 对于精确数学,只要有可能,就会使用给定的精确数值。For example, numbers in comparisons are used exactly as given without a change in value. 例如,比较中的数字完全按照给定值使用,值没有变化。In strict SQL mode, for INSERT into a column with an exact data type (DECIMAL or integer), a number is inserted with its exact value if it is within the column range. 在严格SQL模式下,对于插入到具有精确数据类型(DECIMAL或整型数)的列中,如果数字在列范围内,则插入其精确值。When retrieved, the value should be the same as what was inserted. 检索时,该值应与插入的值相同。(If strict SQL mode is not enabled, truncation for INSERT is permissible.)(如果未启用严格SQL模式,则允许对INSERT进行截断。)

Handling of a numeric expression depends on what kind of values the expression contains:数值表达式的处理取决于表达式包含的值的类型:

If a numeric expression contains any strings, they are converted to double-precision floating-point values and the expression is approximate.如果数值表达式包含任何字符串,它们将转换为双精度浮点值,并且表达式是近似的。

Inserts into numeric columns are affected by the SQL mode, which is controlled by the sql_mode system variable. 插入数值列受SQL模式的影响,SQL模式由sql_mode系统变量控制。(See Section 5.1.11, “Server SQL Modes”.) (见第5.1.11节,“服务器SQL模式”。)The following discussion mentions strict mode (selected by the STRICT_ALL_TABLES or STRICT_TRANS_TABLES mode values) and ERROR_FOR_DIVISION_BY_ZERO. 下面的讨论提到了严格模式(由STRICT_ALL_TABLESSTRICT_TRANS_TABLES模式值选择)和ERROR_FOR_DIVISION_BY_ZEROTo turn on all restrictions, you can simply use TRADITIONAL mode, which includes both strict mode values and ERROR_FOR_DIVISION_BY_ZERO:要启用所有限制,只需使用TRADITIONAL模式,其中包括严格模式值和ERROR_FOR_DIVISION_BY_ZERO

SET sql_mode='TRADITIONAL';

If a number is inserted into an exact type column (DECIMAL or integer), it is inserted with its exact value if it is within the column range and precision.如果在精确类型列(DECIMAL或整数)中插入一个数字,则在列范围和精度内插入该数字的精确值。

If the value has too many digits in the fractional part, rounding occurs and a note is generated. 如果该值在小数部分的位数过多,则会进行舍入并生成注释。Rounding is done as described in Section 12.25.4, “Rounding Behavior”. 舍入按照第12.25.4节,“舍入行为”所述进行。Truncation due to rounding of the fractional part is not an error, even in strict mode.即使在严格模式下,小数部分舍入导致的截断也不是错误。

If the value has too many digits in the integer part, it is too large (out of range) and is handled as follows:如果该值的整数部分位数过多,则表示该值太大(超出范围),并按以下方式处理:

For DECIMAL literals, in addition to the precision limit of 65 digits, there is a limit on how long the text of the literal can be. 对于DECIMAL文本,除了精度限制为65位之外,还对文本的长度有限制。If the value exceeds approximately 80 characters, unexpected results can occur. 如果该值超过大约80个字符,则可能会出现意外结果。For example:例如:

mysql> SELECT
CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
+------------------+
| val              |
+------------------+
| 9999999999999.99 |
+------------------+
1 row in set, 2 warnings (0.00 sec)

mysql> SHOW WARNINGS;
+---------+------+----------------------------------------------+
| Level   | Code | Message                                      |
+---------+------+----------------------------------------------+
| Warning | 1292 | Truncated incorrect DECIMAL value: '20'      |
| Warning | 1264 | Out of range value for column 'val' at row 1 |
+---------+------+----------------------------------------------+
2 rows in set (0.00 sec)

Underflow is not detected, so underflow handling is undefined.未检测到下溢,因此未定义下溢处理。

For inserts of strings into numeric columns, conversion from string to number is handled as follows if the string has nonnumeric contents:对于在数字列中插入字符串,如果字符串包含非数字内容,则按以下方式处理从字符串到数字的转换:

By default, division by zero produces a result of NULL and no warning. 默认情况下,被零除的结果为NULL,没有警告。By setting the SQL mode appropriately, division by zero can be restricted.通过适当地设置SQL模式,可以限制被零除。

With the ERROR_FOR_DIVISION_BY_ZERO SQL mode enabled, MySQL handles division by zero differently:如果启用了ERROR_FOR_DIVISION_BY_ZEROSQL模式,MySQL将以不同的方式处理按零除法:

In other words, inserts and updates involving expressions that perform division by zero can be treated as errors, but this requires ERROR_FOR_DIVISION_BY_ZERO in addition to strict mode.换言之,涉及执行零除运算的表达式的插入和更新可以被视为错误,但除了严格模式外,这还需要ERROR_FOR_DIVISION_BY_ZERO

Suppose that we have this statement:假设我们有这样的语句:

INSERT INTO t SET i = 1/0;

This is what happens for combinations of strict and ERROR_FOR_DIVISION_BY_ZERO modes.对于严格和ERROR_FOR_DIVISION_BY_ZERO模式的组合,这就是结果。

sql_mode ValueResult结果
'' (Default)No warning, no error; i is set to NULL.无警告,无错误;i设置为NULL
strictNo warning, no error; i is set to NULL.无警告,无错误;i设置为NULL
ERROR_FOR_DIVISION_BY_ZEROWarning, no error; i is set to NULL.警告,无错误;i设置为NULL
strict,ERROR_FOR_DIVISION_BY_ZEROError condition; no row is inserted.误差条件;未插入行。