sql_mode :(STRICT_TRANS_TABLES与STRICT_ALL_TABLES 区别)

Posted 小刀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql_mode :(STRICT_TRANS_TABLES与STRICT_ALL_TABLES 区别)相关的知识,希望对你有一定的参考价值。

http://blog.csdn.net/wulantian/article/details/8905573

http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_auto_create_user

http://blog.csdn.net/dslztx/article/details/47176549

http://www.cnblogs.com/javaleon/p/4024761.html

复制代码
mysql> create table test( id int not null auto_increment primary key,browsertype enum(\'ie\',\'firefox\',\'360browser\'),version int );
mysql> insert into test(browsertype) values(\'ie\');
mysql> select * from test;
+----+-------------+---------+
| id | browsertype | version |
+----+-------------+---------+
|  1 | ie          |    NULL |
+----+-------------+---------+
1 row in set (0.00 sec)

mysql> show create table test;

 CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `browsertype` enum(\'ie\',\'firefox\',\'360browser\') DEFAULT NULL,
  `version` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 |

mysql> insert into test(browsertype) values(\'maxthon\');
Query OK, 1 row affected, 1 warning (0.19 sec)                     //warings

mysql> show warnings; 
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning | 1265 | Data truncated for column \'browsertype\' at row 1 |
+---------+------+--------------------------------------------------+
1 row in set (0.15 sec)

mysql> insert into test(browsertype,version) values(\'firefox\',2);
Query OK, 1 row affected (0.17 sec)

mysql> insert into test(browsertype,version) values(\'360browser\',\'a\'); 
Query OK, 1 row affected, 1 warning (0.16 sec)                            //warnings 第5条记录,类型值不同,插入了 version 字段值为0

mysql> select * from test;
+----+-------------+---------+
| id | browsertype | version |
+----+-------------+---------+
|  1 | ie          |    NULL |
|  2 |             |    NULL |
|  3 |             |    NULL |
|  4 | firefox     |       2 |
|  5 | 360browser  |       0 |
+----+-------------+---------+
5 rows in set (0.00 sec)

mysql> set sql_mode ="STRICT_TRANS_TABLES";                           //设置 严格模式
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test(browsertype,version) values(\'360browser\',\'a\');              //报错了并没有插入进出
ERROR 1366 (HY000): Incorrect integer value: \'a\' for column \'version\' at row 1   

mysql> select * from test;
+----+-------------+---------+
| id | browsertype | version |
+----+-------------+---------+
| 1 |   ie      | NULL |
| 2 |          | NULL |
| 3 |          | NULL |
| 4 | firefox     | 2    |
| 5 | 360browser   | 0    |
+----+-------------+---------+
5 rows in set (0.01 sec)

//并没有插入进出


mysql> set sql_mode=ansi;                             //设置非严格模式
Query OK, 0 rows affected (0.00 sec)


mysql> insert into test(browsertype,version) values(\'360browser\',\'a\');
Query OK, 1 row affected, 1 warning (0.01 sec)


mysql> select * from test;
+----+-------------+---------+
| id | browsertype | version |
+----+-------------+---------+
| 1 | ie | NULL |
| 2 | | NULL |
| 3 | | NULL |
| 4 | firefox | 2 |
| 5 | 360browser | 0 |
| 6 | 360browser | 0 |
+----+-------------+---------+
6 rows in set (0.00 sec)   //错误的数据已经插入进入表了

 
复制代码

myisam引擎: 

STRICT_TRANS_TABLES与STRICT_ALL_TABLES 区别:

复制代码

CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`browsertype` enum(\'ie\',\'firefox\',\'360browser\') DEFAULT NULL,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

 

mysql> set sql_mode="STRICT_TRANS_TABLES";
Query OK, 0 rows affected (0.00 sec)


mysql> select * from test;
Empty set (0.01 sec)


mysql> insert into test(id,browsertype,version) values (null,"ie",1),(null,"firefox",2),(null,"tt",3);
Query OK, 3 rows affected, 1 warning (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 1


mysql> select * from test;
+----+-------------+---------+
| id | browsertype | version |
+----+-------------+---------+
| 1 | ie        | 1 |
| 2 | firefox    | 2 |
| 3 |         | 3 |
+----+-------------+---------+
3 rows in set (0.00 sec)


 

mysql> set sql_mode="STRICT_ALL_TABLES ";
Query OK, 0 rows affected (0.00 sec)


mysql> insert into test(id,browsertype,version) values (null,"ie",1),(null,"firefox",2),(null,"tt",3);
ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 3
mysql> select * from test;
+----+-------------+---------+
| id | browsertype | version |
+----+-------------+---------+
| 1 | ie        | 1 |
| 2 | firefox     | 2 |
| 3 |           | 3 |
| 4 | ie          | 1 |
| 5 | firefox       | 2 |
+----+-------------+---------+
5 rows in set (0.00 sec)


停止语句执行,存在部分更新的问题
 
复制代码
复制代码
MySQL 处理非法数据

默认情况下,MySQL按照以下规则处理数据越界和其他非正常数据

1、对于数值数据或time数据列,超出合法范围的值将被阶段到最近的取值范围边界;
2、对于字符串数据列(不包括enum、默认情况下,MySQL按照以下规则处理“数据越界”和其他非正常数据
1、对于数值数据或time数据列,超出合法范围的值将被阶段到最近的取值范围边界; 2、对于字符串数据列(不包括enum、set)太长的字符串将被截断到数据列的最大长度,对于ENUM类型数据,MySQL将不合法成员用空字符串代替。如果赋值给某个set数据列包含非法子字符串,那mysql会删除那些子字符串并把剩下的赋值给该数据列 3、对于日期和时间数据列,非法数值会被转换成‘0’值替代 当发生上述情况的时候,MySQL会生成警告, 可使用 show warnings 查看。 4、对于字符串序列,太长的字符串将被截短到数据列的最大长度
如果需要在插入或更新数据时进行更严格的检查,可以启用特殊的SQL MODE; sql_mode=\'strict_all_tables,strict_trans_tables\' 对于支持事务的表,这两种模式是一样的:如果发现某个值缺失或非法,MySQL将抛出错误,语句会停止运行并回滚。 对于不支持事务的表,这两种模式的效果:
1、如果在插入或修第一个数据行时就发现某个值非法或缺失,那该语句直接抛错,语句停止执行。这个和支持事务的数据表行为时一样的。 2、如果在插入或修改第n个(n>1)数据行时才发现错误,那就会出现下面的情况: 2.1 在strict_all_tables模式下,停止语句执行,存在部分更新的问题 2.2 在strict_trans_tables模式下,MySQL将继续执行该语句避免“部分更新问题”,对每个非法值将其转换为最接近的合法值。
配合严格模式的其他几个SQL模式: ERROR_FOR_DIVISION_BY_ZERO: 在严格模式下,遇到以0为除数的情况,拒绝插入数据库,(如果不在严格模式下,MYSQL将生成一条告警,并插入NULL值) NO_ZERO_DATE:在严格模式下,拒绝0日期值进入数据库。 建议采用:strict_trans_tables ERROR_FOR_DIVISION_BY_ZERO 制止错误的另一个办法是在insert或update语句里使用IGNORE关键字,使非法值而导致的错误弱化为一个警告。
复制代码

    innodb引擎下: 严格模式:STRICT_TRANS_TABLES与strict_all_tables 是一样的

复制代码


mysql> CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `browsertype` enum(\'ie\',\'firefox\',\'360browser\') DEFAULT NULL, `version` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=innodb AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.21 sec) mysql> set sql_mode="STRICT_TRANS_TABLES"; Query OK, 0 rows affected (0.00 sec) mysql> insert into test(id,browsertype,version) values (null,"tt",1),(null,"firefox",2),(null,"ie",3); ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 1 mysql> select * from test; Empty set (0.00 sec) mysql> insert into test(id,browsertype,version) values (null,"ie",1),(null,"firefox",2),(null,"tt",3),(null,"ie",4); ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 3 mysql> select * from test; Empty set (0.00 sec)


mysql> set sql_mode="strict_all_tables";
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test(id,browsertype,version) values (null,"tt",1),(null,"firefox",2),(null,"ie",3);
ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 1
mysql> insert into test(id,browsertype,version) values (null,"ie",1),(null,"firefox",2),(null,"tt",3),(null,"ie",4);
ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 3

复制代码

 mysiam引擎下,当第一行出错有出错数据,将不执行当前,以及后面的语句

复制代码
CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `browsertype` enum(\'ie\',\'firefox\',\'360browser\') DEFAULT NULL, `version` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

mysql> set sql_mode="STRICT_TRANS_TABLES"; Query OK, 0 rows affected (0.00 sec) mysql> insert into test(id,browsertype,version) values (null,"tt",1),(null,"firefox",2),(null,"ie",3); ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 1 mysql> select * from test; Empty set (0.00 sec) mysql> set sql_mode="STRICT_ALL_TABLES "; Query OK, 0 rows affected (0.00 sec) mysql> insert into test(id,browsertype,version) values (null,"tt",1),(null,"firefox",2),(null,"ie",3); ERROR 1265 (01000): Data truncated for column \'browsertype\' at row 1 mysql> select * from test; Empty set (0.00 sec)
复制代码

 

复制代码
mysql> set session sql_mode="TRADITIONAL"
mysql> select  @@sql_mode;
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode                                                                                                                                           |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
| STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
复制代码
复制代码
mysql> set session sql_mode="ANSI";
Query OK, 0 rows affected (0.00 sec)

mysql> select  @@sql_mode;
+-------------------------------------------------------------+
| @@sql_mode                                                  |
+-------------------------------------------------------------+
| REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI |
+-------------------------------------------------------------+
1 row in set (0.00 sec)




复制代码

 

复制代码
mysql> SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";    
mysql> create table tt (a int auto_increment primary key);
Query OK, 0 rows affected (0.22 sec)

mysql> insert into tt values(0);
Query OK, 1 row affected (0.17 sec)

mysql> select * from tt;
+---+
| a |
+---+
| 0 |
+---+
1 row in set (0.16 sec)

mysql> insert into tt values(null);
Query OK, 1 row affected (0.17 sec)

mysql> select * from tt;
+---+
| a |
+---+
| 0 |
| 1 |
+---+
2 rows in set (0.00 sec)

mysql> SET SQL_MODE="";
Query OK, 0 rows affected (0.00 sec)

mysql> insert into tt values(0);
Query OK, 1 row affected (0.16 sec)

mysql> select * from tt;
+---+
| a |
+---+
| 0 |
| 1 |
| 2 |
+---+
3 rows in set (0.00 sec)
复制代码

 

复制代码
TRADITIONAL

Before MySQL 5.7.4, and in MySQL 5.7.8 and later:
TRADITIONAL 等价于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION. From MySQL 5.7.4 though 5.7.7:
TRADITIONAL 等价于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION.

The NO_ZERO_IN_DATE, NO_ZERO_DATE, and ERROR_FOR_DIVISION_BY_ZERO modes are not named because in those versions their effects are included in the effects of strict SQL mode (STRICT_ALL_TABLES or STRICT_TRANS_TABLES). Thus, the effects of TRADITIONAL are the same in all MySQL 5.7 versions (and the same as in MySQL 5.6). For additional discussion, see SQL Mode Changes in MySQL 5.7.
复制代码
 \'5.7.10-log\' version: 
\'NO_ZERO_DATE\', \'NO_ZERO_IN_DATE\' and \'ERROR_FOR_DIVISION_BY_ZERO\' sql modes should be used with strict mode.
 They will be merged with strict mode in a future release.
复制代码
The Most Important SQL Modes:

ansi

STRICT_TRANS_TABLES

TRADITIONAL


复制代码
复制代码
Combination SQL Modes:
     ANSI DB2 MAXDB MSSQL MYSQL323 MYSQL40
ORACLE POSTGRESQL TRADITIONAL StrictSQL Mode:
    STRICT_TRANS_TABLES
STRICT_ALL_TABLES


复制代码

 

复制代码
-- ANSI 使sql符合标准sql
This mode changes syntax and behavior to conform more closely to standard SQL


-- STRICT_TRANS_TABLES 如果事务语句有错,则使事务失败
If a value could not be inserted as given into a transactional table, abort the statement


-- TRADITIONAL 使用error替代warning
this mode is “give an error instead of a warning” when inserting an incorrect value into a column


-- ALLOW_INVALID_DATES 允许非法日期
Do not perform full checking of dates. Check only that the month is in the range from 1 to 12 and the day is in the range from 1 to 31
This mode applies to DATE and DATETIME columns. It does not apply TIMESTAMP columns, which always require a valid date
With strict mode disabled, invalid dates such as \'2004-04-31\' are converted to \'0000-00-00\' and a warning is generated. With strict mode enabled, invalid dates generate an error.


-- ANSI_QUOTES 使双引号当在一个标识符,而不 是一个字符串标识
Treat "" as an identifier quote character (like the "`" quote character) and not as a string quote character
--启用 ANSI_QUOTES 表名加双引号正常执行
mysql>  SET sql_mode=\'ANSI_QUOTES\';
Query OK, 0 rows affected (0.01 sec)
mysql> select "id",id from "t" limit 3;
+----+----+
| id | id |
+----+----+
|  1 |  1 |
|  2 |  2 |
+----+----+
3 rows in set (0.00 sec
--关闭 ANSI_QUOTES 表名加双引报错
mysql>  SET sql_mode=\'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION\';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select "id",id from "t" limit 10;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'"t" limit 10\' at line 1


-- ERROR_FOR_DIVISION_BY_ZERO 决定被0整除是后的行为? 
If this mode is not enabled, division by zero inserts NULL and produces no warning.
If this mode is enabled, division by zero inserts NULL and produces a warning.
If this mode and strict mode are enabled, division by zero produces an error, unless IGNORE is given as well. For INSERT IGNORE and UPDATE IGNORE, division by zero inserts NULL and produces a warning.


-- HIGH_NOT_PRECEDENCE 控制 not 的优化级
The precedence of the NOT operator is such that expressions such as NOT a BETWEEN b AND c are parsed as NOT (a BETWEEN b AND c)
mysql> SET sql_mode = \'\';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 0
mysql> SET sql_mode = \'HIGH_NOT_PRECEDENCE\';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 1



-- NO_AUTO_CREATE_USER 阻止grant自动创建用户,如果没有提供密码或空密码是不认的
Prevent the GRANT statement from automatically creating new user accounts if it would otherwise do so, unless authentication information is specified
The statement must specify a nonempty password using IDENTIFIED BY or an authentication plugin using IDENTIFIED WITH


-- NO_AUTO_VALUE_ON_ZERO 当插入null或0者是否对 AUTO_INCREMENT 产生下一个值
NO_AUTO_VALUE_ON_ZERO affects handling of AUTO_INCREMENT columns. Normally, you generate the next sequence number for the column by inserting either NULL or 0 into it. 
NO_AUTO_VALUE_ON_ZERO suppresses this behavior for 0 so that only NULL generates the next sequence number.


-- NO_DIR_IN_CREATE 在创建表或索引时是否忽略目录参数,注意如果主从的目录结构不同,则可使用此参数
When creating a table, ignore all INDEX DIRECTORY and DATA DIRECTORY directives. This option is useful on slave replication servers.


-- NO_ENGINE_SUBSTITUTION 当创建表或修改表时使用了一个非法或disable的存储引擎时,是否使用其它替代的引擎
Control automatic substitution of the default storage engine when a statement such as CREATE TABLE or ALTER TABLE specifies a storage engine that is disabled or not compiled in


-- NO_ZERO_DATE 控制00是否可做为一个日期类型
The NO_ZERO_DATE mode affects whether the server permits \'0000-00-00\' as a valid date. Its effect also depends on whether strict SQL mode is enabled.
If this mode is not enabled, \'0000-00-00\' is permitted and inserts produce no warning.
If this mode is enabled, \'0000-00-00\' is permitted and inserts produce a warning.
If this mode and strict mode are enabled, \'0000-00-00\' is not permitted and inserts produce an error, 
unless IGNORE is given as well. For INSERT IGNORE and UPDATE IGNORE, \'0000-00-00\' is permitted and inserts produce a warning.

-- NO_ZERO_IN_DATE 控制在年份不为0,但月或天是否可为0,影响如上
The NO_ZERO_IN_DATE mode affects whether the server permits dates in which the year part is nonzero but the month or day part is 0


-- ONLY_FULL_GROUP_BY 使group操作符合标准聚合操作
Reject queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on (uniquely determined by) GROUP BY columns


-- PIPES_AS_CONCAT 使双竖线成为连接符,类似于postgresql和oracle中的||
Treat || as a string concatenation operator (same as CONCAT()) rather than as a synonym for OR.


-- STRICT_ALL_TABLES 使严格模式使用于所有的表,非法数据被拒绝,推荐启用
Enable strict SQL mode for all storage engines. Invalid data values are rejected

-- STRICT_TRANS_TABLES 使严格事务模式使用于所有的存储引擎,推荐启用
Enable strict SQL mode for transactional storage engines, and when possible for nontransactional storage engines


-- mysql还针对不同的数据库提供了组合模式
ANSI,DB2,ORACLE,POSTGRESQL,MSSQL
复制代码

 

以上是关于sql_mode :(STRICT_TRANS_TABLES与STRICT_ALL_TABLES 区别)的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的sql_mode合理设置

docker 修改 mysql 5.7 sql_mode

mysql5.6 sql_mode设置为宽松模式

关于插入时sql_mode的报错

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

MySQL的sql_mode模式