1.1.   SQL_MODE设置

在生产环境中强烈建议将这个值设置为严格模式,这样有些问题可以在数据库的设计和开发阶段就能实现,而如果在生产环境下运行数据库后发现这类问题,那么修改的代价将变得十分巨大。此外正确地设置sql_mode还可以做一些约束(constraint)检查的工作。

对于sql_mode的设置,可以在配置文件、客户端、当前会话或者全局会话中设置。

查看sql_mode的设置情况:

mysql>select @@global.sql_mode;

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

|@@global.sql_mode                         |

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

|STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |

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

1 row inset (0.00 sec)

mysql>select @@session.sql_mode;

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

|@@session.sql_mode                        |

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

|STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |

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

1 row inset (0.00 sec)

1.1.1.     STRICT_TRANS_TABLES

严格模式是指将sql_mode变量设置为STRICT_TRANS_TABLES或STRICT_ALL_TABLES中的至少一种

STRICT_TRANS_TABLES:在该模式下,如果一个值不能插入到一个事务表,则中断当前的操作不影响非事务表(例如表的存储引擎为myisam);

1.1.2.     ALLOWS_INVALID_DATES

该选项并不完全对日期的合法性进行检查,只检查月份是否在1-12之间,日期是否在1-31之间。该模式仅对date和datetime类型有效,而对timestamp无效,因为timestamp总是要求一个合法的输入。

1.1.3.     ANSI_QUOTES

启用ANSI_QUOTES后,不能使用双引号来引用字符串,因为它将被解释为识别符。

mysql>create table z(a varchar(10))engine=innodb;

Query OK,0 rows affected (0.02 sec)

mysql>insert into z select "aaa";

Query OK,1 row affected (0.01 sec)

Records:1  Duplicates: 0  Warnings: 0

mysql>set sql_mode='ANSI_QUOTES';

Query OK,0 rows affected (0.00 sec)

mysql>insert into z select "aaa";

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

mysql>

1.1.4.     ERROR_FOR_DIVISION_BY_ZERO

在insert或者update过程中,如果数据被零除(或MOD(X,0))则产生错误(否则为警告)。如果未给出该模式,那么数据被零除时,mysql返回NULL。如果用到INSERT IGNORE或者UPDATE IGNORE中,mysql生成被零除警告,但操作结果为NULL。

1.1.5.     HIGH_NOT_PRECEDENCE

启用HIGH_NOT_PRECEDENCE:操作符的优先顺序表达式。例如not a between b and c被解释为NOT (a between a and b)。启用HIGH_NOT_PRECEDENCE SQL模式,可以获得以前版本的更高优先级的结果。

mysql>select 0 between -1 and 1;

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

| 0between -1 and 1 |

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

|                  1 |

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

1 row inset (0.00 sec)

mysql>select not 0 between -1 and 1;

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

| not 0between -1 and 1 |

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

|                      0 |

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

1 row inset (0.00 sec)

mysql>set sql_mode='high_not_precedence';

Query OK,0 rows affected (0.00 sec)

mysql>select 0 between -1 and 1;

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

| 0between -1 and 1 |

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

|                  1 |

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

1 row inset (0.01 sec)

mysql>select not 0 between -1 and 1;

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

| not 0between -1 and 1 |

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

|                      1 |

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

1 row inset (0.00 sec)

被解释为(not 0) between -1 and 1结果完全相反。

1.1.6.     ignore_space

忽略函数名和括号之间的空格:

mysql>select max(a) from t;

+--------+

| max(a)|

+--------+

|    105 |

+--------+

1 row inset (0.00 sec)

mysql>select max (a) fromt;

ERROR1630 (42000): FUNCTION test.max does not exist. Check the 'Function NameParsing and Resolution' section in the Reference Manual

mysql>set sql_mode='ignore_space';

Query OK,0 rows affected (0.00 sec)

mysql>select max (a) from t;

+---------+

| max (a)|

+---------+

|     105 |

+---------+

1 row inset (0.00 sec)

1.1.7.     NO_AUTO_CREATE_USER

禁止grant创建密码为空的用户

mysql>select @@sql_mode;

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

|@@sql_mode          |

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

|NO_AUTO_CREATE_USER |

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

1 row inset (0.00 sec)

mysql>set sql_mode='';

Query OK,0 rows affected (0.00 sec)

mysql>grant all privileges on *.* to gf@'%';

Query OK,0 rows affected (0.00 sec)

mysql>set sql_mode='NO_AUTO_CREATE_USER';

Query OK,0 rows affected (0.00 sec)

mysql>grant all privileges on *.* to gf1@'%';

ERROR1133 (42000): Can't find any matching row in the user table

mysql>grant all privileges on *.* to gf1@'%' identified by 123456;

ERROR1064 (42000): You have an error in your SQL syntax; check the manual thatcorresponds to your MySQL server version for the right syntax to use near'123456' at line 1

mysql>grant all privileges on *.* to gf5@'%' identified by 123456;

ERROR1064 (42000): You have an error in your SQL syntax; check the manual thatcorresponds to your MySQL server version for the right syntax to use near'123456' at line 1

1.1.8.     NO_AUTO_VALUE_ON_ZERO

该选项影响列为自增长的插入。在默认设置下,插入0或者null代表生成下一个自增长值。如果用户希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。

mysql>create table tt(id int primary key auto_increment);

Query OK,0 rows affected (0.02 sec)

mysql>explain tt\G;

***************************1. row ***************************

Field: id

Type: int(11)

Null: NO

Key: PRI

Default:NULL

Extra: auto_increment

1 row inset (0.00 sec)

ERROR:

No queryspecified

mysql>insert into tt values(0);

Query OK,1 row affected (0.02 sec)

mysql>insert into tt values(null);

Query OK,1 row affected (0.00 sec)

mysql>insert into tt values(5);

Query OK,1 row affected (0.00 sec)

mysql>select * from tt;

+----+

| id |

+----+

|  2 |

|  4 |

|  5 |

+----+

3 rows inset (0.00 sec)

mysql>set sql_mode='no_auto_value_on_zero';

Query OK,0 rows affected (0.00 sec)

mysql>truncate table tt;

Query OK,0 rows affected (0.01 sec)

mysql>insert into tt values(0);

Query OK,1 row affected (0.01 sec)

mysql>insert into tt values(null);

Query OK,1 row affected (0.00 sec)

mysql>insert into tt values(5);

Query OK,1 row affected (0.01 sec)

mysql>select * from tt;

+----+

| id |

+----+

|  0 |

|  2 |

|  5 |

+----+

3 rows inset (0.01 sec)

只是对0插入有效。

1.1.9.     NO_BACKSLASH_ESCAPES

反斜杠“\”作为普通字符而非转义字符:

mysql>set sql_mode='NO_BACKSLASH_ESCAPES';

Query OK,0 rows affected (0.00 sec)

mysql>select '\\'\G;

***************************1. row ***************************

\\: \\

1 row inset (0.00 sec)

ERROR:

No queryspecified

mysql>set sql_mode='';

Query OK,0 rows affected (0.00 sec)

mysql>select '\\'\G;

***************************1. row ***************************

\: \

1 row inset (0.00 sec)

1.1.10. NO_DIR_IN_CREATE

在创建表时忽视所有INDEXDIRETORY和DATA DIRECTORY的选项。

1.1.11. NO_ENGINE_SUBSTITUTION

如果需要的存储引擎被禁用或者未编译,那么抛出错误。

1.1.12. NO_UNSIGNED_SUBSTITUTION

启用这个选项后,两个UNSIGNED类型相减返回SIGNED类型。

1.1.13. NO_ZERO_DATE

在非严格模式下,可以插入形如“00-00-0000:00:00”的非法日期,mysql仅抛出一个警告,而启用该选项后,mysql不允许插入零日期,插入0日期会抛出错误而非警告。

mysql>set sql_mode='no_zero_date,strict_trans_tables';

Query OK,0 rows affected, 1 warning (0.00 sec)

mysql>insert into tt values(null,'00-00-00 00:00:00');

ERROR1292 (22007): Incorrect datetime value: '00-00-00 00:00:00' for column 'date'at row 1

mysql>insert into tt values(null,'2014-12-02 00:00:00');

Query OK,1 row affected (0.01 sec)

mysql>select * from tt;

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

| id |date                |

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

|  0 | NULL                |

|  2 | NULL                |

|  5 | NULL                |

|  6 | NULL                |

|  8 | 0000-00-00 00:00:00 |

| 10 |0000-00-00 00:00:00 |

| 12 |0000-00-00 00:00:00 |

| 14 |2014-12-02 00:00:00 |

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

8 rows inset (0.00 sec)

注意一定是在strict_trans_tables,否则只是警告:

mysql>set sql_mode='no_zero_date';

Query OK,0 rows affected, 1 warning (0.00 sec)

mysql>insert into tt values(null,'00-00-00 00:00:00');

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

mysql>show warnings;

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

| Level   | Code | Message                                       |

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

| Warning| 1264 | Out of range value for column 'date' at row 1 |

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

1 row inset (0.00 sec)

mysql>select * from tt;

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

| id |date                |

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

|  0 | NULL                |

|  2 | NULL                |

|  5 | NULL                |

|  6 | NULL                |

|  8 | 0000-00-00 00:00:00 |

| 10 |0000-00-00 00:00:00 |

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

6 rows inset (0.00 sec)

1.1.14. NO_ZERO_IN_DATE

在严格模式下,不允许日期和月份为零:采用日期和月份为零的格式时mysql会直接抛出错误而非警告:

mysql>set sql_mode='NO_ZERO_IN_DATE';

Query OK,0 rows affected, 1 warning (0.00 sec)

mysql>TRUNCATE TABLE tt;

Query OK,0 rows affected (0.00 sec)

mysql>insert into tt values(null,'2014-12-02 00:00:00');

Query OK,1 row affected (0.00 sec)

mysql>insert into tt values(null,'2014-12-00 00:00:00');

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

mysql>show warnings;

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

|Level   | Code | Message                                       |

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

| Warning| 1264 | Out of range value for column 'date' at row 1 |

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

1 row in set(0.00 sec)

mysql>select * from tt;

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

| id |date                |

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

|  1 | 2014-12-02 00:00:00 |

|  2 | 0000-00-00 00:00:00 |

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

2 rows inset (0.00 sec)

mysql>set sql_mode='NO_ZERO_IN_DATE,strict_trans_tables';

Query OK,0 rows affected, 1 warning (0.00 sec)

mysql>insert into tt values(null,'2014-12-00 00:00:00');

ERROR1292 (22007): Incorrect datetime value: '2014-12-00 00:00:00' for column 'date'at row 1

mysql>

1.1.15. ONLY_FULL_GROUP_BY

对于GROUP by聚合操作,如果在select中的列没有在GROUP BY中出现,那么sql语句是不合法的,因为a列不在group by从句中。

mysql>select id,sum(date) from tt group by date;

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

| id |sum(date)      |

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

|  2 |              0 |

|  1 | 20141202000000 |

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

2 rows inset (0.00 sec)

mysql>set sql_mode='ONLY_FULL_GROUP_BY';

Query OK,0 rows affected (0.00 sec)

mysql>select id,sum(date) from tt group by date;

ERROR1055 (42000): 'gf.tt.id' isn't in GROUP BY

mysql>

1.1.16. PAD_CHAR_TO_FULL_LENGTH

对于char类型,不要截断空洞数据。空洞数据就是自动填充值为0x20的数据。

默认情况下:

mysql>create table ttt(a char(5));

Query OK,0 rows affected (0.01 sec)

mysql>insert into ttt select 'a';

Query OK,1 row affected (0.00 sec)

Records:1  Duplicates: 0  Warnings: 0

mysql>select a,char_length(a),hex(a) from ttt;

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

| a    | char_length(a) | hex(a) |

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

| a    |              1 | 61     |

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

1 row inset (0.00 sec)

默认字符长度为1,数据库对后面的空洞数据进行了截断。

mysql>set sql_mode='pad_char_to_full_length';

Query OK,0 rows affected (0.00 sec)

mysql>select a,char_length(a),hex(a) from ttt;

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

| a     | char_length(a) | hex(a)     |

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

| a     |              5 | 6120202020 |

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

1 row inset (0.00 sec)

反映的是实际存储的内容。

1.1.17. PIPES_AS_CONCAT

将“||”视为字符串的联接操作符而非运算符,这个和oracle数据库是一样的,也和字符串的拼接函数concat相类似。

mysql>select 'a'||'b'||'c';

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

|'a'||'b'||'c' |

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

|             0 |

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

1 row inset, 3 warnings (0.00 sec)

mysql>show warnings;

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

|Level   | Code | Message                               |

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

| Warning| 1292 | Truncated incorrect DOUBLE value: 'a' |

| Warning| 1292 | Truncated incorrect DOUBLE value: 'b' |

| Warning| 1292 | Truncated incorrect DOUBLE value: 'c' |

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

3 rows inset (0.00 sec)

mysql>set sql_mode='pipes_as_concat';

Query OK,0 rows affected (0.00 sec)

mysql>select 'a'||'b'||'c';

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

|'a'||'b'||'c' |

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

|abc           |

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

1 row inset (0.00 sec)

1.1.18. REAL_AS_FLOAT

将real视为float的同义词而不是double的同义词。

1.1.19. STRICT_ALL_TABLES

对所有引擎的表都启用严格模式。STRICT_TRANS_TABLES只对支持事务的表启用严格模式。

在严格模式下,一旦任何操作的数据产生问题,都会终止当前的操作。

对于启用STRICT_ALL_TABLES选项的非事务引擎来说,这时数据可能停留在一个未知的状态,这可能不是所有非事务引擎原意看到的一种情况,因此需要非常小心这个选项可能带来的潜在影响。

1.1.20. SQL_MODE的选项组合

名称
等同于选项
ANSI
REAL_AS_FLOAT、PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE
ORACLE
REAL_AS_FLOAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NP_TABLE_OPTIONS、NO_FIELD_OPTIONS、NO_AUTO_CREATE_USER
TRADITIONAL
STRICT_TRANS_TABLES、STRICT_ALL_TABLES、NO_ZERO_DATE、NO_ZERO_IN_DATE、ERROT_FOR_DIVIDION_BY_ZERO、NO_ AUTO_CREATE_USER、NO_ENGINE_SUBSTITITION
MSSQL
PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NP_TABLE_OPTIONS、NO_FIELD_OPTIONS
DB2
PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NP_TABLE_OPTIONS、NO_FIELD_OPTIONS
MYSQL323
NO_FIELD_OPTIONS、HIGH_NOT_PRECEDENCE
MYSQL40
NO_FIELD_OPTIONS、HIGH_NOT_PRECEDENCE
MAXDB
PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NP_TABLE_OPTIONS、NO_FIELD_OPTIONS、NO_AUTO_CREATE_USER
 
 
 

mysql SQL_MODE设置的更多相关文章

  1. Mysql sql_mode设置 timestamp default 0000-00-00 00:00:00 创建表失败处理

    往数据库里创建新表的时候报错: [Err] 1067 - Invalid default value for 'updateTime' DROP TABLE IF EXISTS `passwd_res ...

  2. MySQL数据类型:SQL_MODE设置不容忽视

    [IT168 技术]SQL_MODE可能是比较容易让开发人员和DBA忽略的一个变量,默认为空.SQL_MODE的设置其实是比较冒险的一种设置,因为在这种设置下可以允许一些非法操作,比如可以将NULL插 ...

  3. MySQL timespan设置 sql_mode设置

    Timespan设置: 在MySQL5.7版本中创建表 CREATE TABLE `investor_seat` ( `id` int(11) NOT NULL AUTO_INCREMENT , `i ...

  4. MySQL::SQL_MODE

    SQL_MODE可能是比较容易让开发人员和DBA忽略的一个变量,默认为空.SQL_MODE的设置其实是比较冒险的一种设置,因为在这种设置下可以允许一些非法操作,比如可以将NULL插入NOT NULL的 ...

  5. MySQL sql_mode 说明(及处理一起 sql_mode 引发的问题)(转)

    1. MySQL莫名变成了 Strict SQL Mode 最近测试组那边反应数据库部分写入失败,app层提示是插入成功,但表里面里面没有产生数据,而两个写入操作的另外一个表有数据.因为 insert ...

  6. 【转】MySQL sql_mode 说明(及处理一起 sql_mode 引发的问题)

    1. MySQL 莫名变成了 Strict SQL Mode 最近测试组那边反应数据库部分写入失败,app层提示是插入成功,但表里面里面没有产生数据,而两个写入操作的另外一个表有数据.因为 inser ...

  7. SQL_MODE设置讲解

    SQL_MODE可能是比较容易让开发人员和DBA忽略的一个变量,默认为空.SQL_MODE的设置其实是比较冒险的一种设置,因为在这种设置下 可以允许一些非法操作,比如可以将NULL插入NOT NULL ...

  8. docker 下修改 mysql sql_mode和配置文件

    原文:docker 下修改 mysql sql_mode和配置文件 打开PowerShell 首先创建mysql容器,这里我们指定使用mysql5.7的版本 docker run -d -p 3306 ...

  9. MySQL sql_mode 说明(及处理一起 sql_mode 引发的问题)

    1. MySQL莫名变成了 Strict SQL Mode 最近测试组那边反应数据库部分写入失败,app层提示是插入成功,但表里面里面没有产生数据,而两个写入操作的另外一个表有数据.因为 insert ...

随机推荐

  1. 一个很吊的swing循环生成窗口。

    import javax.swing.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; publi ...

  2. POJ 1724 Roads

    题意:有R条路,每条路都有一定的路长和花费,问在总的花费小于一定的值的情况下,从1到N的最短路程         注意:这里两点之间单向边,且可能存在很多条路,所以只能用邻接表存储.思路:用dijks ...

  3. hdu 4447 Yuanfang, What Do You Think?

    思路: 这题有个结论也可以自己归纳: 对于给定的n,其约数用pi表示 T(n)=T(p1)T(p2)……T(pn)T(n') 其中T(n')是这个式子所独有的也就是 T(n')=(x^n-1)/T(p ...

  4. 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇

    从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...

  5. Project Euler 83:Path sum: four ways 路径和:4个方向

    Path sum: four ways NOTE: This problem is a significantly more challenging version of Problem 81. In ...

  6. mysql外键详解

    1.1.MySQL中“键”和“索引”的定义相同,所以外键和主键一样也是索引的一种.不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引.用于外键关系的字段必须在所有的参 ...

  7. Spring + JMS + ActiveMQ实现简单的消息队列(监听器异步实现)

    首先声明:以下内容均是在网上找别人的博客综合学习而成的,可能会发现某些代码与其他博主的相同,由于参考的文章比较多,这里对你们表示感谢,就不一一列举,如果有侵权的地方,请通知我,我可以把该文章删除. 1 ...

  8. WCF入门(十)---WCF事务

    事务处理在WCF(Windows Communication Foundation)是一套遵循一些性质,统称为ACID的操作.这里,如果一个操作出现故障,整个系统就会自动失败.如网上订单生成,就可能使 ...

  9. Linux文件目录结构详解

    整理自<鸟哥的私房菜> 对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于 ...

  10. gsp序列模式挖掘

    数据挖掘进阶之序列模式挖掘GSP算法 绪 继续数据挖掘方面算法的讲解,前面讲解了数据挖掘中关联规则算法FP-Growth的实现.此篇博文主要讲解基于有趣性度量标准的GSP序列模式挖掘算法.有关论文后期 ...