文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  超出範圍和溢位處理

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 TABLELOAD DATAUPDATE 和多列 INSERT 陳述式。在嚴格模式下,這些陳述式會失敗,並且某些或所有值不會被插入或變更,具體取決於表格是否為交易表格和其他因素。詳細資訊請參閱第 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)'

如果啟用 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 模式,則會發生錯誤並且欄位保持不變。