Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


MySQL 8.0 リファレンスマニュアル  /  ...  /  範囲外およびオーバーフローの処理

このページは機械翻訳したものです。

11.1.7 範囲外およびオーバーフローの処理

MySQL が、カラムデータ型の許可できる範囲外にある数値カラムに値を格納すると、結果は、その時点で有効な SQL モードによって異なります。

  • 厳密な SQL モードが有効な場合、SQL 標準に従って、MySQL は範囲外の値を拒否してエラーを表示し、挿入は失敗します。

  • 制限モードが有効になっていない場合、MySQL はカラムのデータ型範囲の適切なエンドポイントに値をクリップし、かわりに結果の値を格納します。

    範囲外の値が整数カラムに割り当てられると、MySQL は、カラムデータ型の範囲の対応する終点を表す値を格納します。

    浮動小数点または固定小数点カラムに、指定された (またはデフォルトの) 精度とスケールによって暗示された範囲を超えた値が割り当てられると、MySQL はその範囲の対応する終点を表す値を格納します。

テーブル t1 に次の定義があるとします。

Press CTRL+C to copy
CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);

厳密な SQL モードを有効にすると、範囲外エラーが発生します:

Press CTRL+C to copy
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 モードが有効になっていない場合、警告付きでクリッピングが発生します:

Press CTRL+C to copy
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 ステートメントの警告としてレポートされます。 厳密モードでは、これらのステートメントは失敗し、テーブルがトランザクションテーブルかどうかやその他の要因に応じて、一部またはすべての値が挿入または変更されません。 詳細は、セクション5.1.11「サーバー SQL モード」を参照してください。

数値式の評価中にオーバーフローすると、エラーが発生します。 たとえば、符号付きの BIGINT の最大値は 9223372036854775807 なので、次の式ではエラーが発生します。

Press CTRL+C to copy
mysql> SELECT 9223372036854775807 + 1; ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'

この場合に演算を成功させるには、値を符号なしに変換します。

Press CTRL+C to copy
mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1; +-------------------------------------------+ | CAST(9223372036854775807 AS UNSIGNED) + 1 | +-------------------------------------------+ | 9223372036854775808 | +-------------------------------------------+

オーバーフローが起きるかどうかはオペランドの範囲に応じて異なります。したがって、前述の式を処理するもう 1 つの方法として、DECIMAL 値に整数より大きな範囲があるので正確な値の演算を使用します。

Press CTRL+C to copy
mysql> SELECT 9223372036854775807.0 + 1; +---------------------------+ | 9223372036854775807.0 + 1 | +---------------------------+ | 9223372036854775808.0 | +---------------------------+

一方が UNSIGNED 型のときに 2 つの整数値の間で減算を行うと、デフォルトでは符号なしの結果が生成されます。 それ以外の場合は、エラーが発生します:

Press CTRL+C to copy
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 モードが有効な場合は、結果は負になります。

Press CTRL+C to copy
mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION'; mysql> SELECT CAST(0 AS UNSIGNED) - 1; +-------------------------+ | CAST(0 AS UNSIGNED) - 1 | +-------------------------+ | -1 | +-------------------------+

このような演算の結果を使用して UNSIGNED 整数カラムが更新されると、結果はそのカラム型の最大値に切り落とされます。NO_UNSIGNED_SUBTRACTION が有効になっている場合は、0 に切り落とされます。 厳密な SQL モードが有効になっている場合は、エラーが発生し、カラムは変わりません。