When MySQL stores a value in a numeric column that is outside the permissible range of the column data type, the result depends on the SQL mode in effect at the time:当MySQL在数值列中存储的值超出了列数据类型的允许范围时,结果取决于当时有效的SQL模式:
If strict SQL mode is enabled, MySQL rejects the out-of-range value with an error, and the insert fails, in accordance with the SQL standard.如果启用了严格的SQL模式,MySQL将根据SQL标准拒绝超出范围的值并返回一个错误,并且插入失败。
If no restrictive modes are enabled, MySQL clips the value to the appropriate endpoint of the column data type range and stores the resulting value instead.如果没有启用限制模式,MySQL会将值剪辑到列数据类型范围的适当端点,并存储结果值。
When an out-of-range value is assigned to an integer column, MySQL stores the value representing the corresponding endpoint of the column data type range.当一个超出范围的值被分配给一个整数列时,MySQL存储表示列数据类型范围的相应端点的值。
When a floating-point or fixed-point column is assigned a value that exceeds the range implied by the specified (or default) precision and scale, MySQL stores the value representing the corresponding endpoint of that range.当为浮点或定点列分配的值超出指定(或默认)精度和小数位数所暗示的范围时,MySQL将存储表示该范围对应端点的值。
Suppose that a table 假设表t1
has this definition:t1
具有以下定义:
CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);
With strict SQL mode enabled, an out of range error occurs:启用严格SQL模式时,会发生超出范围的错误:
mysql>SET sql_mode = 'TRADITIONAL';
mysql>INSERT INTO t1 (i1, i2) VALUES(256, 256);
ERROR 1264 (22003): Out of range value for column 'i1' at row 1 mysql>SELECT * FROM t1;
Empty set (0.00 sec)
With strict SQL mode not enabled, clipping with warnings occurs:如果未启用严格SQL模式,则会出现带有警告的剪裁:
mysql>SET sql_mode = '';
mysql>INSERT INTO t1 (i1, i2) VALUES(256, 256);
mysql>SHOW WARNINGS;
+---------+------+---------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------+ | Warning | 1264 | Out of range value for column 'i1' at row 1 | | Warning | 1264 | Out of range value for column 'i2' at row 1 | +---------+------+---------------------------------------------+ mysql>SELECT * FROM t1;
+------+------+ | i1 | i2 | +------+------+ | 127 | 255 | +------+------+
When strict SQL mode is not enabled, column-assignment conversions that occur due to clipping are reported as warnings for 如果未启用严格SQL模式,则由于剪切而发生的列分配转换将报告为ALTER TABLE
, LOAD DATA
, UPDATE
, and multiple-row INSERT
statements. ALTER TABLE
、LOAD DATA
、UPDATE
和多行INSERT
语句的警告。In strict mode, these statements fail, and some or all the values are not inserted or changed, depending on whether the table is a transactional table and other factors. 在严格模式下,这些语句失败,部分或全部值不会插入或更改,这取决于表是否是事务表以及其他因素。For details, see Section 5.1.11, “Server SQL Modes”.有关详细信息,请参阅第5.1.11节,“服务器SQL模式”。
Overflow during numeric expression evaluation results in an error. 数值表达式求值期间溢出导致错误。For example, the largest signed BIGINT
value is 9223372036854775807, so the following expression produces an error:
mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
To enable the operation to succeed in this case, convert the value to unsigned;要使操作在这种情况下成功,请将值转换为无符号;
mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;
+-------------------------------------------+
| CAST(9223372036854775807 AS UNSIGNED) + 1 |
+-------------------------------------------+
| 9223372036854775808 |
+-------------------------------------------+
Whether overflow occurs depends on the range of the operands, so another way to handle the preceding expression is to use exact-value arithmetic because 是否发生溢出取决于操作数的范围,因此处理前面表达式的另一种方法是使用精确值算术,因为DECIMAL
values have a larger range than integers:DECIMAL
值的范围大于整数:
mysql> SELECT 9223372036854775807.0 + 1;
+---------------------------+
| 9223372036854775807.0 + 1 |
+---------------------------+
| 9223372036854775808.0 |
+---------------------------+
Subtraction between integer values, where one is of type 默认情况下,整数值之间的减法(其中一个值的类型为UNSIGNED
, produces an unsigned result by default. UNSIGNED
)生成无符号结果。If the result would otherwise have been negative, an error results:如果结果本来是负数,则会产生错误:
mysql>SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec) mysql>SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
If the 如果启用了NO_UNSIGNED_SUBTRACTION
SQL mode is enabled, the result is negative:NO_UNSIGNED_SUBTRACTION
SQL模式,则结果为负:
mysql>SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
mysql>SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+ | CAST(0 AS UNSIGNED) - 1 | +-------------------------+ | -1 | +-------------------------+
If the result of such an operation is used to update an 如果使用此操作的结果更新UNSIGNED
integer column, the result is clipped to the maximum value for the column type, or clipped to 0 if NO_UNSIGNED_SUBTRACTION
is enabled. UNSIGNED
整数列,则结果将被剪裁为列类型的最大值,如果未启用NO_UNSIGNED_SUBTRACTION
,则结果将被剪裁为0。If strict SQL mode is enabled, an error occurs and the column remains unchanged.如果启用严格SQL模式,则会发生错误,列保持不变。