Spec-Zone.ru › MySQL 9.2

13.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 эти инструкции завершаются неудачно, и некоторые или все значения не вставляются или не изменяются, в зависимости от того, является ли таблица транзакционной и от других факторов. Подробности см. в Разделе 7.1.11, «Режимы 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.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/out-of-range-and-overflow.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API