執行減法查詢時:
SELECT store - freez AS less FROM products;
報錯:
Data truncation: BIGINT UNSIGNED value is out of range in '(`products`.`store` - `products`.`freez`)'
store 與 freez 欄位型別為 BIGINT UNSIGNED(無號整數)。NO_UNSIGNED_SUBTRACTION 未開啟,導致兩個無號數相減若結果為負數,超出無號數範圍(0 ~ 18446744073709551615)而報錯。sql_mode 控制。
SET SESSION sql_mode = 'NO_UNSIGNED_SUBTRACTION';
SELECT store - freez AS less FROM products;
此模式下,無號數相減結果允許為負數,自動轉為有號數型別回傳。
-- 當前實例生效(重啟失效)
SET GLOBAL sql_mode = CONCAT(@@global.sql_mode, ',NO_UNSIGNED_SUBTRACTION');
-- 永久生效:編輯 /etc/my.cnf
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_UNSIGNED_SUBTRACTION"
SELECT CAST(store AS SIGNED) - CAST(freez AS SIGNED) AS less FROM products;
-- 或
SELECT (store + 0) - (freez + 0) AS less FROM products; -- 隱含轉型為有號數
| 模式值 | 作用 |
|---|---|
| NO_UNSIGNED_SUBTRACTION | 允許無號數相減產生負數結果 |
| STRICT_TRANS_TABLES | 嚴格模式:資料截斷、無效值報錯而非警告 |
| NO_ENGINE_SUBSTITUTION | 指定儲存引擎不可用時不自動替換為預設引擎 |
| ONLY_FULL_GROUP_BY | GROUP BY 必須包含所有非聚合欄位 (5.7+ 預設開啟) |
| ANSI_QUOTES | 雙引號視為識別符而非字串 |
SELECT @@session.sql_mode;
SELECT @@global.sql_mode;
SIGNED。SET SESSION sql_mode = '...'。