MySQL 數值型別溢位處理
來,考考大家一個問題,在 MySQL 中當某一列設定為
int(0)
時會發生什麼 ?
為了演示這個問題,我們先要建立一個表
DROP TABLE IF EXISTS `na`;
CREATE TABLE `na` (
n1 INT(0) NOT NULL DEFAULT '0',
n2 INT(11) NOT NULL DEFAULT '0'
);
然後我們使用下面的語句往
na
表中插入一些資料
mysql> INSERT INTO `na` VALUES(520,520),(5201314,5201314);
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
最後我們讀取出來看看
mysql> SELECT * FROM na;
+---------+---------+
| n1 | n2 |
+---------+---------+
| 520 | 520 |
| 5201314 | 5201314 |
+---------+---------+
2 rows in set (0.00 sec)
對的,好像什麼都不會發生,沒什麼問題才是對的,我就怕有什麼問題…哈哈
我們這一章節來講講整型溢位問題。
MySQL 數值型別溢位處理
當 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)
當嚴格模式被禁用,值可以插入,但會被裁剪,並且引發一個警告
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 INFILE
,
UPDATE
和多行
INSERT
等語句會由於裁剪而發生的列分配轉換並且引發一個警告。
而如果啟用了嚴格模式,這些語句會直接失敗,並且未插入或更改部分或全部值,具體取決於表是否為事務表和其他因素。
數值表示式求值過程中的溢位會導致錯誤,例如,因為最大的有符號 BIGINT 值是 9223372036854775807,因此以下表示式會產生錯誤
mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
為了在這種情況下使操作成功,需要將值轉換為
unsigned
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 模式,則會發生錯誤並且列保持不變。
後記
一切都是套路,套路….基本都和 SQL 模式有關…
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946007/viewspace-2658397/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql 字串型別的數值欄位按照數值的大小進行排序MySql字串型別排序
- 檢查型別是否溢位型別
- Laravel 處理 MySQL geometry 空間型別LaravelMySql型別
- 多型關聯自定義的型別欄位的處理多型型別
- CSS 小結筆記之文字溢位處理CSS筆記
- 整數溢位
- TypeScript 數值型別TypeScript型別
- Python數值型別Python型別
- MySQL欄位型別最全解析MySql型別
- mysql表操作(alter)/mysql欄位型別MySql型別
- JavaScript - 變數、值、型別JavaScript變數型別
- 使用紋理的RGBA通道儲存float型別數值型別
- mysql中數值型資料有哪兩個類別?MySql
- 譯-MYSQL5.7參考手冊--數值型別概述MySql型別
- MySql資料庫 數值型別的顯示寬度MySql資料庫型別
- Mysql 資料型別之整數型別MySQL 資料型別
- XSD 數值資料型別資料型別
- oracle數值型別漫談Oracle型別
- JavaScript之number型別的數值轉換成某某進位制JavaScript型別
- 譯-MYSQL5.7參考手冊--11.1.1數值型別概述MySql型別
- 程式錯誤型別及其處理型別
- 使用MySQL的geometry型別處理經緯度距離問題MySql型別
- js基本語法之 值型別(資料型別)(變數型別)JS資料型別變數
- JavaScript 字串轉換數值型別JavaScript字串型別
- Js實現Object按照值的某個欄位(數值型別)的大小進行排序JSObject型別排序
- Go 函式多返回值錯誤處理與error 型別介紹Go函式Error型別
- MySQL中TEXT與BLOB欄位型別的區別MySql型別
- 溢位、上溢、下溢
- (1) Pytorch深度學習—數值處理PyTorch深度學習
- 咖啡汪日誌———數值計算,精度、舍入、溢位(極客時間)
- MySQL text型別不允許有預設值MySql型別
- 0-4 Python 基礎資料型別-數值型別Python資料型別
- 06 Windows批處理之整數和浮點資料型別Windows資料型別
- 基於clamp.js封裝vue指令,處理多行文字的溢位LAMPJS封裝Vue
- java.sql.SQLException: 數字溢位JavaSQLException
- 值型別和引用型別型別
- Spark儲存Parquet資料到Hive,對map、array、struct欄位型別的處理SparkHiveStruct型別
- 二進位制漏洞挖掘之整數溢位