91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL 數值類型溢出處理

發布時間:2020-08-10 23:46:55 來源:ITPUB博客 閱讀:169 作者:互聯網搬運工 欄目:編程語言

推薦閱讀吊打面試官!MySQL靈魂100問,你能答出多少?

來,考考大家一個問題,在 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 會將值裁剪到列數據類型范圍的上下限值并存儲

    1. 當超出范圍的值分配給整數列時,MySQL 會存儲表示列數據類型范圍的相應端點的值

    2. 當為浮點或定點列分配的值超出指定(或默認)精度和比例所隱含的范圍時,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 TABLELOAD DATA INFILEUPDATE 和多行 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 模式有關…

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天水市| 来凤县| 长丰县| 满城县| 辉南县| 屏东市| 都匀市| 崇仁县| 杨浦区| 措美县| 秦皇岛市| 拉萨市| 车致| 南平市| 增城市| 黄平县| 镇远县| 武清区| 鄂托克前旗| 获嘉县| 佛冈县| 新宁县| 株洲市| 荔浦县| 奉节县| 常宁市| 清流县| 五常市| 香河县| 贵南县| 南阳市| 南京市| 宁强县| 衡阳市| 卢龙县| 崇左市| 武平县| 师宗县| 兴安盟| 德钦县| 隆德县|