1. 程式人生 > >MYSQL SQL模式 (未完成)

MYSQL SQL模式 (未完成)

引用 文件 禁用 創建用戶 是個 同義詞 ted fma sele

SQL模式影響MySQL支持的SQL語法和執行的數據驗證檢查。
本篇內容根據官方手冊https://dev.mysql.com/doc/refman/5.7/en/sql-mode.htmlvgli 進行整理
已完成部分:設置和查詢SQL模式、MySQL5.7中SQL模式的完整列表
未完成部分:嚴格模式的詳細描述、IGNORE關鍵字和嚴格模式的關系、在MySQL5.7中SQL模式的更改

設置和查詢SQL模式

通過修改sql_mode變量的值來改變SQL模式。
SQL模式可以在全局級別下設置,也可以在會話級別下設置。在數據庫啟動時和數據庫運行時都可以對sql_mode的值進行修改。

在數據庫啟動時設置SQL模式

在命令行中使用--sql_mode=‘modes‘選項,或者在配置文件中使用sql_mode="modes"。

modes是一個以逗號分隔的模式的列表。
要清除SQL模式,將它設置為一個空的字符串,例如sql_mode=""

在數據庫運行時設置SQL模式

使用SET語句來更改sql_mode的值,例如:

SET GLOBAL sql_mode = ‘modes‘;
SET SESSION sql_mode = ‘modes‘;

設置全局變量的值需要SUPER權限,設置後應用到之後所有客戶端連接的操作。
設置session變量只應用於當前客戶端,每個客戶端都可以在任何時候更改它的sessionSQL模式。

查詢SQL模式

要確定當前使用的SQL模式,使用以下語句進行查詢

SELECT @@GLOBAL.sql_mode;

SELECT @@SESSION.sql_mode;

主要的SQL模式

主要的sql_mode的值為以下幾種:

  • ANSI
    這是一個組合模式,它似的語法和行為更符合標準的SQL
  • STRICT_TRANS_TABLES
    對事務表的嚴格模式。在這種模式下,如果一個值不能被插入到事務表中,則終止該語句。對於非事務表,如果不能插入的值發生在單行語句或者多行語句的第一行,也會終止該語句。
  • TRADITIONAL
    傳統模式,這也是一個組合模式。在這種模式下,當插入一個不正確的值時,會給出錯誤而不是警告。(在非事務性存儲引擎中,可能這不是我們想要的,因為在發生錯誤時語句會中斷,但是在錯誤發生前進行的數據修改不能夠回滾,從而導致部分更新。)

SQL模式的完整列表

sql模式可以大致分為以下幾類

嚴格模式(包括STRICT_ALL_TABLES和STRICT_TRANS_TABLES)

  • STRICT_ALL_TABLES
    對於所有存儲引擎啟用嚴格模式,無效的值會被拒絕。
  • STRICT_TRANS_TABLES
    對於事務存儲引擎啟用嚴格模式,並在可能的情況下對飛事務存儲引擎啟用嚴格模式。

在MySQL5.7.4到MySQL5.7.7中,嚴格模式包括ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE和NO_ZERO_IN_DATE的效果。

用來限制0值,和嚴格模式一同使用的

  • NO_ZERO_DATE
    影響數據庫是否允許‘0000-00-00‘作為一個有效的日期。其效果還取決於是否啟用了嚴格模式
    如果啟用了該模式,允許‘0000-00-00‘值並且插入不會產生警告
    如果禁用了該模式,允許‘0000-00-00‘值但是插入會產生警告
    如果該模式和嚴格模式同時啟用,除非同時給出IGNORE,否則不允許‘0000-00-00‘插入並產生錯誤
  • NO_ZERO_IN_DATE
    影響數據庫是否允許在年份非0時,月份或日期為0。其效果還取決於是否啟用了嚴格模式。
    如果啟用了該模式,允許包括0的日期值並且插入不會產生警告。
    如果禁用了該模式,允許包括0的日期值但是插入會產生警告。
    如果該模式和嚴格模式同時使用,除非同時給出IGNORE,否則不允許插入包含0的日期值並且插入會產生錯誤。對於INSERT IGNORE和UPDATE IGNORE,包含0的日期值會作為‘0000-00-00‘插入並產生警告
  • ERROR_FOR_DIVISION_BY_ZERO
    影響數據庫是否允許將0作為除數,包括MOD(N,0)。其效果還取決於是否啟用了嚴格模式
    如果啟用了該模式,允許以0作為除數並且插入不會產生警告
    如果禁用了該模式,允許以0作為除數但是插入會產生警告
    如果該模式和嚴格模式同時使用,除非同時給出IGNORE,否則不允許以0作為除數並且插入會產生錯誤。對於INSERT IGNORE和UPDATE IGNORE,以0作為除數會插入NULL並產生警告。

在MySQL5.7.4以前版本中,以上三個模式被棄用
在MySQL5.7.4到MySQL5.7.7中,以上三個模式不產生作用,他們的效果包含在嚴格模式中。
在MySQL5.7.8及以後版本中,以上三個模式才有自己單獨的作用,而不是嚴格模式的一部分。但是,他們應該和嚴格模式一起使用,並且默認情況下他們都是開啟的。如果使用嚴格模式而不使用上述模式會產生警告,如果使用上述模式中的任何一個但是不啟用嚴格模式也會產生警告。
由於以上三個模式以棄用,在後續的MySQL版本中,他們作為一個單獨的模式名會被刪除,並且他們的效果將包含在嚴格模式中。

用來說明符號的作用的

  • ANSI_QUOTES
    將"作為標識符(與相同)而不是作為字符串的引用符號。在啟用此模式的情況下,仍然可以使用作為引用標識符,但是不能使用雙引號來引用文本字符串。
  • PIPES_AS_CONCAT
    將||作為字符串連接操作符(與CONCAT()相同),而不是作為OR的同義詞
  • REAL_AS_FLOAT
    將REAL作為FLOAT的同義詞。默認情況下,MySQL將REAL視為DOUBLE的同義詞。
  • NO_BACKSLASH_ESCAPES
    禁用反斜杠字符()作為字符串中的轉義字符。在啟用此模式後,反斜杠就變成了一個普通字符。

    影響語句的方式或結果的

  • NO_UNSIGNED_SUBTRACTION
    對於整數之間的減法,如果一個值的類型是UNSIGNED,默認生成一個無符號整型的結果,但是如果結果是個負數,就會出現錯誤
    如果啟用NO_UNSIGNED_SUBTRACTION,結果為負時不會報錯

  • IGNORE_SPACE
    在函數名和(中間允許空格。這將導致內置函數名被當作保留字處理。因此,與函數名相同的標識符必須被引用。
    例如,因為存在COUNT()函數,直接使用count作為表名會產生錯誤

    mysql> CREATE TABLE count (i INT);
    ERROR 1064 (42000): You have an error in your SQL syntax

    應該將表名引用起來:

    mysql> CREATE TABLE count (i INT);
    Query OK, 0 rows affected (0.00 sec)

  • HIGH_NOT_PRECEDENCE
    在MySQL5.7中,NOT a BETWEEN b AND C的計算順序為,NOT (a BETWEEN b AND c)
    啟用HIGH_NOT_PRECEDENCE後,該順序更改為(NOT a) BETWEEN b AND c

用來限制SHOW CREATE TABLE語句的輸出結果的

  • NO_FIELD_OPTIONS
    在SHOW CREATE TABLE的輸出中不顯示特定與MySQL的列選項
  • NO_KEY_OPTIONS
    在SHOW CREATE TABLE的輸出中不顯示特定與MySQL的索引選項
  • NO_TABLE_OPTIONS
    在SHOW CRETAE TABLE的輸出中不顯示特定與MySQL的表選項

影響數據庫的行為的

  • NO_AUTO_CREATE_USER
    如果不指定身份驗證信息,GRANT語句不會自動創建用戶。GRANT語句必須使用IDENTIFIED BY語句指定一個非空的密碼或者使用IDENTIFIED WITH語句指定認證插件。
    建議使用CREATE USER語句來創建用戶
  • NO_AUTO_VALUE_ON_ZERO
    NO_AUTO_VALUE_ON_ZERO 影響對於自動增長列的處理。通常,通過插入NULL或者0來生成下一個序列號。NO_AUTO_VALUE_ON_ZERO允許在自動增長列中插入0值,這樣只有插入NULL才能生成下一個序列號。
  • NO_ENGINE_SUBSTITUTION
    當一個語句,例如CREATE TABLE或ALTER TABLE指定一個禁用或者未編譯的存儲引擎時,自動替換為默認存儲引擎。當沒有啟用NO_ENGINE_SUBSTITUTION時。如果指定的存儲引擎不可用,對於CREATE TABLE,使用默認存儲引擎並生成警告,對於ALTER TABLE,生成警告並且不會對表進行修改。
    當啟用NO_ENGINE_SUBSTITUTION時,如果指定的存儲引擎不可用,無論是創建表還是修改表都會導致錯誤。
  • PAD_CHAR_TO_FULL_LENGTH
    默認情況下,在查詢時,CHAR列末尾的空格會自動刪除。啟用PAD_CHAR_TO_FULL_LENGTH,則不會刪除空格,將查詢到的CHAR值補全到完整的列長度。
  • NO_DIR_IN_CREATE
    在創建表時,忽略所有INDEX DIRECTORY和DATA DIRECTORY指令。這個選項在復制的從庫中很有用。
  • ONLY_FULL_GROUP_BY
    在SELECT HAVING或者ORDER BY列表中不能包含沒有在GROUP BY子句中命名或者不能通過GROUP BY子句唯一確定的列
    請參考http://www.ywnds.com/?p=8184
  • ALLOW_INVALID_DATES
    允許無效的日期,只檢查月份在1-12之間和日期在1-31之間,不對日期進行完整的檢查。這個模式只應用與DATE和DATETIME列。在嚴格模式禁用的情況下,諸如"2018-02-31"這樣的無效日期會被轉換為‘0000-00-00‘並產生警告,如果啟用了嚴格模式,這樣的無效日期會產生錯誤。

SQL模式的組合

以下模式是對上述SQL模式完整列表中的部分組合的縮寫

名稱 完整列表
ANSI REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE,和 (在MySQL 5.7.5) ONLY_FULL_GROUP_BY
DB2 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS
MSSQL PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS
POSTGRESQL PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS
ORACLE PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER
MAXDB PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER
TRADITIONAL STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION

MYSQL SQL模式 (未完成)