11.1.7 Обработка значений вне диапазона и переполнения
При хранении MySQL значения в числовом столбце, выходящего за допустимый диапазон типа данных столбца, результат зависит от режима SQL, действующего в данный момент:
Если режим строгого SQL включён, MySQL отклоняет значение, выходящее за пределы диапазона, с ошибкой, и вставка не выполняется, в соответствии со стандартом SQL.
-
Если не включены режимы с ограничениями, MySQL обрезает значение до соответствующей границы диапазона типа данных столбца и сохраняет полученное значение вместо исходного.
Когда значение, выходящее за пределы диапазона, присваивается целочисленному столбцу, MySQL сохраняет значение, соответствующее границе диапазона типа данных столбца.
Когда столбцу с плавающей или фиксированной точкой присваивается значение, превышающее диапазон, заданный точностью и масштабом (или по умолчанию), MySQL сохраняет значение, соответствующее соответствующей границе этого диапазона.
Предположим, что таблица t1 имеет такое определение:
CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);
При включённом режиме строгого 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)
При отключённом режиме строгого 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 |
+------+------+
Когда режим строгого SQL не включён, преобразования столбца присваивания, происходящие из-за обрезки, сообщаются как предупреждения для ALTER TABLE, LOAD DATA, UPDATE и многострочных INSERT операторов. В режиме строгого SQL эти операторы завершаются ошибкой, и некоторые или все значения не вставляются или не изменяются, в зависимости от того, является ли таблица транзакционной таблицей и других факторов. Подробности см. в Разделе 5.1.10, «Режимы SQL сервера».
Переполнение при вычислении арифметического выражения приводит к ошибке. Например, наибольшее знаковое BIGINT значение составляет 9223372036854775807, поэтому следующее выражение приводит к ошибке:
mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
Чтобы операция прошла успешно в этом случае, преобразуйте значение в беззнаковое:
mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;
+-------------------------------------------+
| CAST(9223372036854775807 AS UNSIGNED) + 1 |
+-------------------------------------------+
| 9223372036854775808 |
+-------------------------------------------+
Происходит ли переполнение, зависит от диапазона операндов, поэтому другой способ обработки предыдущего выражения — использование точной арифметики, так как DECIMAL значения имеют больший диапазон, чем целые числа:
mysql> SELECT 9223372036854775807.0 + 1;
+---------------------------+
| 9223372036854775807.0 + 1 |
+---------------------------+
| 9223372036854775808.0 |
+---------------------------+
Вычитание между целочисленными значениями, где одно имеет тип UNSIGNED, по умолчанию даёт беззнаковый результат. Если результат в противном случае был бы отрицательным, возникает ошибка:
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)'
Если включён режим SQL NO_UNSIGNED_SUBTRACTION, результат будет отрицательным:
mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 AS UNSIGNED) - 1 |
+-------------------------+
| -1 |
+-------------------------+
Если результат такой операции используется для обновления столбца UNSIGNED со знаком, результат обрезается до максимального значения для типа столбца или обрезается до 0, если включён NO_UNSIGNED_SUBTRACTION. Если включён режим строгого SQL, возникает ошибка, и столбец остаётся неизменным.
© 2025 Oracle
Licensed under the GPLv2 License.