MySQL支持的SQL模式介紹

SQL模式介紹

MySQL服務(wù)器可以在不同的SQL操作模式,并能應(yīng)用這些模式不同的客戶问顷,根據(jù)不同的價(jià)值SQL模式系統(tǒng) 變量校摩。數(shù)據(jù)庫(kù)管理員可以設(shè)置全局SQL模式相匹配的網(wǎng)站服務(wù)器操作要求,每個(gè)應(yīng)用程序可以設(shè)置會(huì)話 SQL模式自身的要求朱巨。

SQL模式定義MySQL應(yīng)支持哪些SQL語(yǔ)法,以及應(yīng)執(zhí)行哪種數(shù)據(jù)驗(yàn)證檢查枉长。這樣可以更容易地在不同的環(huán)境中使用MySQL冀续,并結(jié)合其它數(shù)據(jù)庫(kù)服務(wù)器使用MySQL。

介紹各SQL模式

ONLY_FULL_GROUP_BY

在嚴(yán)格模式下必峰,不要讓GROUP BY部分中的查詢指向未選擇的列洪唐,否則報(bào)錯(cuò)。

NO_ZERO_DATE

在嚴(yán)格模式吼蚁,不要將’0000-00-00’做為合法日期凭需。你仍然可以用IGNORE選項(xiàng)插入零日期。在非嚴(yán)格模式肝匆,可以接受該日期粒蜈,但會(huì)生成警告。

NO_ZERO_IN_DATE

在嚴(yán)格模式旗国,不接受月或日部分為0的日期(也就是說(shuō)比NO_ZERO_DATE)枯怖,對(duì)年不限制。如果使用IGNORE選項(xiàng)能曾,我們?yōu)轭愃频娜掌诓迦搿?000-00-00’度硝。在非嚴(yán)格模式肿轨,可以接受該日期,但會(huì)生成警告蕊程。

ERROR_FOR_DIVISION_BY_ZERO

在嚴(yán)格模式椒袍,在INSERT或UPDATE過(guò)程中,如果被零除(或MOD(X藻茂,0))驹暑,則產(chǎn)生錯(cuò)誤(否則為警告)。如果未給出該模式辨赐,被零除時(shí)MySQL返回NULL岗钩。如果用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告肖油,但操作結(jié)果為NULL。

NO_AUTO_CREATE_USER

在嚴(yán)格模式下臂港,防止GRANT自動(dòng)創(chuàng)建新用戶森枪,除非還指定了密碼。

NO_ENGINE_SUBSTITUTION

如果需要的存儲(chǔ)引擎被禁用或未編譯审孽,可以防止自動(dòng)替換存儲(chǔ)引擎县袱。

STRICT_TRANS_TABLES

為事務(wù)存儲(chǔ)引擎啟用嚴(yán)格模式,也可能為非事務(wù)存儲(chǔ)引擎啟用嚴(yán)格模式佑力,非法數(shù)據(jù)值被拒絕式散,下面有詳細(xì)說(shuō)明。

嚴(yán)格模式控制MySQL如何處理非法或丟失的輸入值打颤。有幾種原因可以使一個(gè)值為非法暴拄。例如,數(shù)據(jù)類型錯(cuò)誤编饺,不適合列乖篷,或超出范圍。當(dāng)新插入的行不包含某列的沒(méi)有顯示定義DEFAULT子句的值透且,則該值被丟失撕蔼。

對(duì)于事務(wù)表瑰妄,當(dāng)啟用STRICT_ALL_TABLES或STRICT_TRANS_TABLES模式時(shí)吆视,如果語(yǔ)句中有非法或丟失值,則會(huì)出現(xiàn)錯(cuò)誤澳盐。語(yǔ)句被放棄并滾動(dòng)锅论。

對(duì)于非事務(wù)表讼溺,如果插入或更新的第1行出現(xiàn)壞值,兩種模式的行為相同最易。語(yǔ)句被放棄肾胯,表保持不變竖席。如果語(yǔ)句插入或修改多行,并且壞值出現(xiàn)在第2或后面的行敬肚,結(jié)果取決于啟用了哪個(gè)嚴(yán)格選項(xiàng):

對(duì)于STRICT_ALL_TABLES毕荐,MySQL返回錯(cuò)誤并忽視剩余的行。但是艳馒,在這種情況下憎亚,前面的行已經(jīng)被插入或更新。這說(shuō)明你可以部分更新弄慰,這可能不是你想要的第美。要避免這點(diǎn),最好使用單行語(yǔ)句陆爽,因?yàn)檫@樣可以不更改表即可以放棄什往。

對(duì)于STRICT_TRANS_TABLES,MySQL將非法值轉(zhuǎn)換為最接近該列的合法值并插入調(diào)整后的值慌闭。如果值丟失别威,MySQL在列中插入隱式 默認(rèn)值。在任何情況下驴剔,MySQL都會(huì)生成警告而不是給出錯(cuò)誤并繼續(xù)執(zhí)行語(yǔ)句省古。

嚴(yán)格模式不允許非法日期,例如’2004-04-31’丧失。它不允許禁止日期使用“零”部分豺妓,例如’2004-04-00’或”零”日期。要想禁止布讹,應(yīng)在嚴(yán)格模式基礎(chǔ)上琳拭,啟用NO_ZERO_IN_DATE和NO_ZERO_DATE SQL模式。

如果你不使用嚴(yán)格模式(即不啟用STRICT_TRANS_TABLES或STRICT_ALL_TABLES模式)描验,對(duì)于非法或丟失的值臀栈,MySQL將插入調(diào)整后的值并給出警告。在嚴(yán)格模式挠乳,你可以通過(guò)INSERT IGNORE或UPDATE IGNORE來(lái)實(shí)現(xiàn)权薯。

ANSI

更改語(yǔ)法和行為,使其更符合標(biāo)準(zhǔn)SQL睡扬。

TRADITIONAL

Make MySQL的行為象“傳統(tǒng)”SQL數(shù)據(jù)庫(kù)系統(tǒng)盟蚣。該模式的簡(jiǎn)單描述是當(dāng)在列中插入不正確的值時(shí)“給出錯(cuò)誤而不是警告”。注釋:一旦發(fā)現(xiàn)錯(cuò)誤立即放棄INSERT/UPDATE卖怜。如果你使用非事務(wù)存儲(chǔ)引擎屎开,這種方式不是你想要的,因?yàn)槌霈F(xiàn)錯(cuò)誤前進(jìn)行的數(shù)據(jù)更改不會(huì)“滾動(dòng)”马靠,結(jié)果是更新“只進(jìn)行了一部分”奄抽。

ALLOW_INVALID_DATES

在嚴(yán)格模式下不要檢查全部日期蔼两。只檢查1到12之間的月份和1到31之間的日。這在Web應(yīng)用程序中逞度,當(dāng)你從三個(gè)不同的字段獲取年额划、月、日档泽,并且想要確切保存用戶插入的內(nèi)容(不進(jìn)行日期驗(yàn)證)時(shí)很重要俊戳。該模式適用于DATE和DATETIME列。不適合TIMESTAMP列馆匿,TIMESTAMP列需要驗(yàn)證日期抑胎。

啟用嚴(yán)格模式后,服務(wù)器需要合法的月和日渐北,不僅僅是分別在1到12和1到31范圍內(nèi)阿逃。例如,禁用嚴(yán)格模式時(shí)’2004-04-31’是合法的赃蛛,但啟用嚴(yán)格模式后是非法的恃锉。要想在嚴(yán)格模式允許遮掩固定日期,還應(yīng)啟用ALLOW_INVALID_DATES焊虏。

ANSI_QUOTES

將‘”‘視為識(shí)別符引號(hào)(‘`’引號(hào)字符),不要視為字符串的引號(hào)字符秕磷。在ANSI模式诵闭,你可以仍然使用‘`’來(lái)引用識(shí)別符。啟用ANSI_QUOTES后澎嚣,你不能用雙引號(hào)來(lái)引用字符串疏尿,因?yàn)樗唤忉尀樽R(shí)別符。

ERROR_FOR_DIVISION_BY_ZERO

在嚴(yán)格模式易桃,在INSERT或UPDATE過(guò)程中褥琐,如果被零除(或MOD(X,0))晤郑,則產(chǎn)生錯(cuò)誤(否則為警告)敌呈。如果未給出該模式,被零除時(shí)MySQL返回NULL造寝。如果用到INSERT IGNORE或UPDATE IGNORE中磕洪,MySQL生成被零除警告,但操作結(jié)果為NULL诫龙。

HIGH_NOT_PRECEDENCE

NOT操作符的優(yōu)先順序是表達(dá)式例如NOT a BETWEEN b AND c被解釋為NOT (a BETWEEN b AND c)析显。在一些舊版本MySQL中, 表達(dá)式被解釋為(NOT a) BETWEEN b AND c签赃。啟用HIGH_NOT_PRECEDENCESQL模式谷异,可以獲得以前的更高優(yōu)先級(jí)的結(jié)果分尸。

IGNORE_SPACE

允許函數(shù)名和‘(‘之間有空格。強(qiáng)制將所有函數(shù)名視為保存的字歹嘹。結(jié)果是箩绍,如果你想要訪問(wèn)保存為字的數(shù)據(jù)庫(kù)、表或列名荞下,你必須引用它伶选。例如,因?yàn)橛蠻SER()函數(shù)尖昏,mysql數(shù)據(jù)庫(kù)中的user表名和該表內(nèi)的User列被保存下來(lái)仰税,因此你必須引用它們.

NO_AUTO_VALUE_ON_ZERO

NO_AUTO_VALUE_ON_ZERO影響AUTO_INCREMENT列的處理。一般情況抽诉,你可以向該列插入NULL或0生成下一個(gè)序列號(hào)陨簇。NO_AUTO_VALUE_ON_ZERO禁用0,因此只有NULL可以生成下一個(gè)序列號(hào)迹淌。

如果將0保存到表的AUTO_INCREMENT列河绽,該模式會(huì)很有用。(不推薦采用該慣例)唉窃。例如耙饰,如果你用mysqldump轉(zhuǎn)儲(chǔ)表并重載,MySQL遇到0值一般會(huì)生成新的序列號(hào)纹份,生成的表的內(nèi)容與轉(zhuǎn)儲(chǔ)的表不同苟跪。重載轉(zhuǎn)儲(chǔ)文件前啟用NO_AUTO_VALUE_ON_ZERO可以解決該問(wèn)題。mysqldump在輸出中自動(dòng)包括啟用NO_AUTO_VALUE_ON_ZERO的語(yǔ)句蔓涧。

NO_BACKSLASH_ESCAPES

禁用反斜線字符(‘\’)做為字符串內(nèi)的退出字符件已。啟用該模式,反斜線則成為普通字符元暴。

NO_DIR_IN_CREATE

創(chuàng)建表時(shí)篷扩,忽視所有INDEX DIRECTORY和DATA DIRECTORY指令。該選項(xiàng)對(duì)從復(fù)制服務(wù)器有用茉盏。

NO_ENGINE_SUBSTITUTION

如果需要的存儲(chǔ)引擎被禁用或未編譯鉴未,可以防止自動(dòng)替換存儲(chǔ)引擎。

NO_FIELD_OPTIONS

不要在SHOW CREATE TABLE的輸出中打印MySQL專用列選項(xiàng)鸠姨。該模式在可移植模式(portability mode)下用于mysqldump歼狼。

NO_KEY_OPTIONS

不要在SHOW CREATE TABLE的輸出中打印MySQL專用索引選項(xiàng)。該模式在可移植模式(portability mode)下用于mysqldump享怀。

NO_TABLE_OPTIONS

不要在SHOW CREATE TABLE的輸出中打印MySQL專用表選項(xiàng)(例如ENGINE)羽峰。該模式在可移植模式(portability mode)下用于mysqldump。

NO_UNSIGNED_SUBTRACTION

在減運(yùn)算中,如果某個(gè)操作數(shù)沒(méi)有符號(hào)梅屉,不要將結(jié)果標(biāo)記為UNSIGNED值纱。請(qǐng)注意這樣使UNSIGNED BIGINT不能100%用于上下文中。參見(jiàn)12.8節(jié)坯汤,“Cast函數(shù)和操作符”虐唠。

PIPES_AS_CONCAT

將||視為字符串連接操作符(+)(同CONCAT()),而不視為OR惰聂。

REAL_AS_FLOAT

將REAL視為FLOAT的同義詞疆偿,而不是DOUBLE的同義詞。

SQL模式測(cè)試

一搓幌、查看當(dāng)前SQL模式

來(lái)看一下MySQL 5.6&5.7的默認(rèn)SQL模式

# MySQL 5.6 Default SQL_MODE;

mysql> select @@sql_mode;

+--------------------------------------------+

| @@sql_mode???????????????????????????????? |

+--------------------------------------------+

| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |

+--------------------------------------------+

1 row in set (0.00 sec)


# MySQL 5.7 Default SQL_MODE;

mysql> select @@sql_mode;

+-------------------------------------------------------------------------------------------------------------------------------------------+

| @@sql_mode????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????|

+-------------------------------------------------------------------------------------------------------------------------------------------+

| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |

+-------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

MySQL 5.7對(duì)數(shù)據(jù)的嚴(yán)謹(jǐn)性和一致性上比之前版本要提升很多

二杆故、指定模式

你可以在配置文件中用:

1sql_mode = "modes"

選項(xiàng)啟動(dòng)mysqld來(lái)設(shè)置默認(rèn)SQL模式,modes是用逗號(hào)(‘,’)間隔開(kāi)的一系列不同的模式溉愁。如果你想要重設(shè)处铛,該值還可以為空(sql-mode =””)。

你還可以動(dòng)態(tài)改變SQL模式:

1SET [SESSION|GLOBAL] sql_mode='modes'

設(shè)置GLOBAL變量時(shí)需要擁有SUPER權(quán)限拐揭,并且會(huì)影響從那時(shí)起連接的所有客戶端的操作撤蟆。設(shè)置SESSION變量只影響當(dāng)前的客戶端。任何客戶端可以隨時(shí)更改自己的會(huì)話sql_mode值堂污。

三家肯、示例演示

1.在嚴(yán)格的模式下

mysql> create table tbl_kenyon(id int null,vname varchar(6));

Query OK, 0 rows affected (0.12 sec)


mysql> insert into tbl_kenyon values(1,'123456');

Query OK, 1 row affected (0.00 sec)


mysql> insert into tbl_kenyon values(1,'1234567');

ERROR 1406 (22001): Data too long for column 'vname' at row 1


mysql> insert into tbl_kenyon values('','123456');

ERROR 1366 (HY000): Incorrect integer value: '' for column 'id' at row 1


mysql> insert into tbl_kenyon values(null,'123456');

Query OK, 1 row affected (0.01 sec)

2.在非嚴(yán)格的模式下

mysql> set @@sql_mode='';

Query OK, 0 rows affected (0.00 sec)


mysql> insert into tbl_kenyon values(99,'123456');

Query OK, 1 row affected (0.00 sec)


mysql> insert into tbl_kenyon values(1,'1234567');

Query OK, 1 row affected, 1 warning (0.00 sec)


mysql> insert into tbl_kenyon values('','123456');

Query OK, 1 row affected, 1 warning (0.00 sec)


mysql> show warnings;

+---------+------+------------------------------------------------------+

| Level | Code | Message |

+---------+------+------------------------------------------------------+

| Warning | 1366 | Incorrect integer value: '' for column 'id' at row 1 |

+---------+------+------------------------------------------------------+

1 row in set (0.00 sec)

四、 應(yīng)用場(chǎng)景

兩種模式各有利弊盟猖,通常生產(chǎn)上會(huì)設(shè)置嚴(yán)格模式讨衣,可以保證數(shù)據(jù)的完整性。非嚴(yán)格模式并不一定就是差的扒披,在數(shù)據(jù)一致性要求不嚴(yán)的場(chǎng)景下某些忽略警告操作可能更方便值依,比如不同版本數(shù)據(jù)庫(kù)的非關(guān)鍵數(shù)據(jù)導(dǎo)入:

mysql> load data infile '/data/source_data/trace/tbl_msg.sql' into table tbl_msg;

ERROR 1366 (HY000): Incorrect integer value: 'NULL' for column 'pid' at row 1

換個(gè)模式導(dǎo)入:

mysql> set @@session.sql_mode='';

Query OK, 0 rows affected (0.00 sec)


mysql> load data infile '/data/source_data/trace/ tbl_msg.sql' into table tbl_msg;

Query OK, 23525 rows affected, 65535 warnings (2.80 sec)

Records: 23525 Deleted: 0 Skipped: 0 Warnings: 185707


轉(zhuǎn)自:http://www.ywnds.com/?p=7049

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末圃泡,一起剝皮案震驚了整個(gè)濱河市碟案,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颇蜡,老刑警劉巖价说,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異风秤,居然都是意外死亡鳖目,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)缤弦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)领迈,“玉大人,你說(shuō)我怎么就攤上這事±晖保” “怎么了衷蜓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)尘喝。 經(jīng)常有香客問(wèn)我磁浇,道長(zhǎng),這世上最難降的妖魔是什么朽褪? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任置吓,我火速辦了婚禮,結(jié)果婚禮上缔赠,老公的妹妹穿的比我還像新娘衍锚。我一直安慰自己,他們只是感情好橡淑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布构拳。 她就那樣靜靜地躺著,像睡著了一般梁棠。 火紅的嫁衣襯著肌膚如雪置森。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天符糊,我揣著相機(jī)與錄音凫海,去河邊找鬼。 笑死男娄,一個(gè)胖子當(dāng)著我的面吹牛行贪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播模闲,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼建瘫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了尸折?” 一聲冷哼從身側(cè)響起啰脚,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎实夹,沒(méi)想到半個(gè)月后橄浓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亮航,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年荸实,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缴淋。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡准给,死狀恐怖泄朴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情露氮,我是刑警寧澤叼旋,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站沦辙,受9級(jí)特大地震影響夫植,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜油讯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一详民、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陌兑,春花似錦沈跨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至软驰,卻和暖如春涧窒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锭亏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工纠吴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慧瘤。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓戴已,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锅减。 傳聞我的和親對(duì)象是個(gè)殘疾皇子糖儡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容