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 在严格SQL模式下,对于插入到具有精确数据类型(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. DECIMAL
或整型数)的列中,如果数字在列范围内,则插入其精确值。When retrieved, the value should be the same as what was inserted. 检索时,该值应与插入的值相同。(If strict SQL mode is not enabled, truncation for (如果未启用严格SQL模式,则允许对INSERT
is permissible.)INSERT
进行截断。)
Handling of a numeric expression depends on what kind of values the expression contains:数值表达式的处理取决于表达式包含的值的类型:
If any approximate values are present, the expression is approximate and is evaluated using floating-point arithmetic.如果存在任何近似值,则表达式是近似的,并使用浮点运算进行计算。
If no approximate values are present, the expression contains only exact values. 如果不存在近似值,则表达式仅包含精确值。If any exact value contains a fractional part (a value following the decimal point), the expression is evaluated using 如果任何精确值包含小数部分(小数点后的值),则使用DECIMAL
exact arithmetic and has a precision of 65 digits. DECIMAL
精确算术计算表达式,精度为65位。The term “exact” is subject to the limits of what can be represented in binary. 术语“精确”受二进制表示的限制。For example, 例如,1.0/3.0
can be approximated in decimal notation as .333...
, but not written as an exact number, so (1.0/3.0)*3.0
does not evaluate to exactly 1.0
.1.0/3.0
可以用十进制表示法近似为.333...
,但不能写成精确的数字,因此(1.0/3.0)*3.0
的计算结果不能精确到1.0
。
Otherwise, the expression contains only integer values. 否则,表达式只包含整数值。The expression is exact and is evaluated using integer arithmetic and has a precision the same as 表达式是精确的,使用整数运算进行计算,精度与BIGINT
(64 bits).BIGINT
(64位)相同。
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模式的影响,SQL模式由sql_mode
system variable. 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_TABLES
或STRICT_TRANS_TABLES
模式值选择)和ERROR_FOR_DIVISION_BY_ZERO
。To 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:如果该值的整数部分位数过多,则表示该值太大(超出范围),并按以下方式处理:
If strict mode is not enabled, the value is truncated to the nearest legal value and a warning is generated.如果未启用严格模式,则该值将被截断为最接近的合法值,并生成警告。
If strict mode is enabled, an overflow error occurs.如果启用严格模式,则会发生溢出错误。
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:对于在数字列中插入字符串,如果字符串包含非数字内容,则按以下方式处理从字符串到数字的转换:
A string that does not begin with a number cannot be used as a number and produces an error in strict mode, or a warning otherwise. 不以数字开头的字符串不能用作数字并在严格模式下产生错误或警告。This includes the empty string.这包括空字符串。
A string that begins with a number can be converted, but the trailing nonnumeric portion is truncated. 可以转换以数字开头的字符串,但后面的非数字部分将被截断。If the truncated portion contains anything other than spaces, this produces an error in strict mode, or a warning otherwise.如果截断部分包含除空格以外的任何内容,则在严格模式下会产生错误,否则会产生警告。
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_ZERO
SQL模式,MySQL将以不同的方式处理按零除法:
If strict mode is not enabled, a warning occurs.如果未启用严格模式,则会出现警告。
If strict mode is enabled, inserts and updates involving division by zero are prohibited, and an error occurs.如果启用严格模式,则禁止涉及除零的插入和更新,并发生错误。
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 | |
---|---|
'' (Default) | i is set to NULL .i 设置为NULL 。 |
strict | i is set to NULL .i 设置为NULL 。 |
ERROR_FOR_DIVISION_BY_ZERO | i is set to NULL .i 设置为NULL 。 |
strict,ERROR_FOR_DIVISION_BY_ZERO |