首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL SQL Mode 完整指南:嚴格模式、兼容模式與數據校驗實戰

     編輯:MySQL 資料庫相關知識

SQL Mode 核心作用

定義 MySQL 支援的 SQL 語法規則、數據校驗嚴格程度、錯誤處理行為。可動態調整,無需重啟。

查看與設置

-- 查看當前會話/全局模式
SELECT @@SESSION.sql_mode, @@GLOBAL.sql_mode;

-- 會話級臨時生效
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';

-- 全局持久化 (需寫入 my.cnf)
[mysqld]
sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY'

常用模式值對照表

模式值行為描述推薦場景
STRICT_TRANS_TABLES事務表插入非法值直接報錯回滾;非事務表僅首行報錯生產環境必開
STRICT_ALL_TABLES所有表 (含非事務) 嚴格模式對數據質量極高要求
TRADITIONALSTRICT_TRANS_TABLES + NO_ZERO_DATE + NO_ZERO_IN_DATE + ERROR_FOR_DIVISION_BY_ZERO 組合傳統嚴格模式
ANSI語法行為向標準 SQL 靠攏異構遷移兼容
ONLY_FULL_GROUP_BYGROUP BY 必須包含所有非聚合列 (5.7+ 默認開啟)防止語義模糊查詢
NO_ZERO_DATE禁止 '0000-00-00' 日期業務不允許空日期
NO_ZERO_IN_DATE禁止月/日為 0 的日期 (如 '2024-00-01')日期完整性校驗
ERROR_FOR_DIVISION_BY_ZERO除零報錯而非返回 NULL計算準確性要求高
NO_ENGINE_SUBSTITUTION指定引擎不可用時報錯而非靜默降級防止靜默性能退化
PIPES_AS_CONCAT|| 作為字符串連接而非 OROracle/PostgreSQL 兼容
ANSI_QUOTES" 作為識別符引號而非字符串引號標準 SQL 兼容
IGNORE_SPACE允許函數名與括號間有空格兼容舊代碼風格

嚴格模式實戰對比

-- 建表
CREATE TABLE t5 (c1 CHAR(3));

-- 默認模式 (寬鬆)
INSERT INTO t5 VALUES('abcd');
-- Query OK, 1 row affected, 1 warning (Data truncated)
SELECT * FROM t5;  -- 'abc' (靜默截斷)

-- 開啟 STRICT_TRANS_TABLES
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
INSERT INTO t5 VALUES('abcd');
-- ERROR 1406 (22001): Data too long for column 'c1' at row 1

異構數據庫兼容模式組合

目標數據庫建議 sql_mode 組合
DB2PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS
OraclePIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER
SQL ServerPIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS
PostgreSQLPIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS
MaxDBPIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER

數據校驗與轉換功能

  1. 日期合法性:NO_ZERO_DATE + NO_ZERO_IN_DATE 拒絕非法日期
  2. 除零保護:ERROR_FOR_DIVISION_BY_ZERO 使 1/0 拋錯
  3. 識別符引號:ANSI_QUOTES 讓 "col" 成列名,字符串必須用 'str'
  4. 關閉轉義:NO_BACKSLASH_ESCAPES 讓反斜線成普通字符
  5. 字符串連接:PIPES_AS_CONCAT 使 'a' || 'b' 等價 CONCAT('a','b')

風險提示

  • 非事務引擎 (MyISAM) 下 STRICT_TRANS_TABLES 發生錯誤時,已執行的 DML 無法回滾,導致部分更新
  • 老應用遷移時建議:先開啟 sql_mode='' 觀察 Warning,逐步收緊
  • 5.7+ 默認已含 ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES 等,升級前必測
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved