Spec-Zone .ru
спецификации, руководства, описания, API

11.2.6. Из диапазона и Обработка Переполнения

Когда MySQL хранит значение в числовом столбце, который является вне допустимого диапазона типа данных столбца, результат зависит от режима SQL в действительности в это время:

О преобразованиях присвоения столбца, которые происходят из-за отсечения, когда MySQL не работает в строгом режиме, сообщают как предупреждения для ALTER TABLE, LOAD DATA INFILE, UPDATE, и многократная строка INSERT операторы. В строгом режиме, эти операторы сбой, и некоторые или все значения не будут введены или изменены, в зависимости от того, является ли таблица транзакционной таблицей и другими факторами. Для получения дополнительной информации см. Раздел 5.1.7, "Режимы SQL Сервера".

В MySQL 5.7 переполнение во время оценки числового выражения приводит к ошибке. Например, подписанное самое большое 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 5.5.5, если результат иначе был бы отрицателен, это становится максимальным целочисленным значением:

mysql> SET sql_mode =
        '';mysql> SELECT CAST(0 AS UNSIGNED) - 1;+-------------------------+| CAST(0 AS UNSIGNED) - 1 |+-------------------------+|    18446744073709551615 |+-------------------------+

С MySQL 5.5.5, если результат иначе был бы отрицателен, заканчивается ошибка:

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)'

Если NO_UNSIGNED_SUBTRACTION Режим SQL включается, результат отрицателен:

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 включается, ошибка происходит, и столбец остается неизменным.