【業務DBA手記八】SQL_MODE詳解

一、概述
SQL_MODE多是比較容易讓開發人員和DBA忽略的一個變量,默認爲空。SQL_MODE的設置實際上是比較冒險的一種設置,由於在這種設置下能夠容許一些非法操做,好比能夠將NULL插入NOT NULL的字段中,也能夠插入一些非法日期,如「2012-12-32」。所以在生產環境中強烈建議開發人員將這個值設爲嚴格模式,這樣有些問題能夠在數據庫的設計和開發階段就能發現,而若是在生產環境下運行數據庫後發現這類問題,那麼修改的代價將變得十分巨大。此外,正確地設置SQL_MODE還能夠作一些約束(Constraint)檢查的工做。

二、案例說明
 mysql> create table zzy_test1 (c1 char(3));
 mysql> insert into zzy_test1 values('abcd');
 mysql> select * from zzy_test1;
    +------+
    | c1   |
    +------+
    | abc  |
    +------+
    1 row in set (0.00 sec)

咱們發現插入的字符被自動截斷了,可是若是咱們本意但願若是長度超過限制就報錯,那麼咱們能夠設置sql_mode爲STRICT_TRANS_TABLES,以下:
    mysql> set session sql_mode='STRICT_TRANS_TABLES'
這樣咱們再執行一樣的操做,mysql就會告訴咱們插入的值太長,操做被終止,以下:
    mysql> insert into zzy_test1 values('abcd');
    ERROR 1406 (22001): Data too long for column 'c1' at row 1

三、參數說明
ONLY_FULL_GROUP_BY:
對於GROUP BY聚合操做,若是在SELECT中的列,沒有在GROUP BY中出現,那麼這個SQL是不合法的,由於列不在GROUP BY從句中

NO_AUTO_VALUE_ON_ZERO:
該值影響自增加列的插入。默認設置下,插入0或NULL表明生成下一個自增加值。若是用戶 但願插入的值爲0,而該列又是自增加的,那麼這個選項就有用了。

STRICT_TRANS_TABLES:
在該模式下,若是一個值不能插入到一個事務表中,則中斷當前的操做,對非事務表不作限制
NO_ZERO_IN_DATE:
在嚴格模式下,不容許日期和月份爲零

NO_ZERO_DATE:
設置該值,mysql數據庫不容許插入零日期,插入零日期會拋出錯誤而不是警告。

ERROR_FOR_DIVISION_BY_ZERO:
 ERROR_FOR_DIVISION_BY_ZERO:在INSERT或UPDATE過程當中,若是數據被零除(或MOD(X,0)),則產生錯誤(不然爲警告)。若是未給出該模式,那麼數據被零除時MySQL返回NULL。若是用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操做結果爲NULL。
NO_AUTO_CREATE_USER:
禁止GRANT建立密碼爲空的用戶

NO_ENGINE_SUBSTITUTION:
若是須要的存儲引擎被禁用或未編譯,那麼拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常

PIPES_AS_CONCAT:
將"||"視爲字符串的鏈接操做符而非或運算符,這和Oracle數據庫是同樣的,也和字符串的拼接函數Concat相相似

ANSI_QUOTES:
啓用ANSI_QUOTES後,不能用雙引號來引用字符串,由於它被解釋爲識別符,只能用單引號
mysql> CREATE TABLE z ( a VARCHAR(10))ENGINE=INNODB;

  Query OK, 0 rows affected (0.00 sec)

  mysql>INSERT INTO z SELECT "aaa";

  Query OK, 1 rows affected (0.00 sec)

  mysql> SET sql_mode='ANSI_QUOTES';

  Query OK, 0 rows affected (0.00 sec)

  mysql> INSERT INTO z SELECT "aaa";

  ERROR 1054 (42S22): Unknown column 'aaa' in 'field list'

ORACLE的sql_mode設置等同:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.
 
若是使用mysql,爲了繼續保留你們使用oracle的習慣,能夠對mysql的sql_mode設置以下:
 
在my.cnf添加以下配置 [mysqld]
sql_mode=' ONLY_FULL_GROUP_BY, NO_AUTO_VALUE_ON_ZERO, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE,
ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION, PIPES_AS_CONCAT, ANSI_QUOTES'





相關文章
相關標籤/搜索