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 に次の定義があるとします。

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 1mysql> 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 ステートメントの警告としてレポートされます。 厳密モードでは、これらのステートメントは失敗し、テーブルがトランザクションテーブルかどうかやその他の要因に応じて、一部またはすべての値が挿入または変更されません。 詳細は、セクション5.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 |+-------------------------------------------+

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

mysql> SELECT 9223372036854775807.0 + 1;+---------------------------+| 9223372036854775807.0 + 1 |+---------------------------+|     9223372036854775808.0 |+---------------------------+

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

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 整数カラムが更新されると、結果はそのカラム型の最大値に切り落とされます。NO_UNSIGNED_SUBTRACTION が有効になっている場合は、0 に切り落とされます。 厳密な SQL モードが有効になっている場合は、エラーが発生し、カラムは変わりません。