码迷,mamicode.com
首页 > 数据库 > 详细

mysql的sql_mode模式

时间:2015-06-23 17:21:59      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

最近将测试环境的MySQL从5.0升级到了5.5,然后升级之后同事说有些insert SQL执行不了,一开始还以为是MySQL版本的问题,

后来查了下发现MySQL是因为MySQL有个sql mode设置,所以查看了下2个MySQL的sql mode设置,发现果然不一样

技术分享

技术分享

果然是不一样的呢,那就学习下MySQL的sql mode吧。

mysql5.0以上版本支持三种sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。
ANSI模式:宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。

TRADITIONAL模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事物时,会进行事物的回滚。

STRICT_TRANS_TABLES模式:严格模式,进行数据的严格校验,错误数据不能插入,报error错误。

首先我们设置ANSI模式.

mysql> show variables like sql_mode;+---------------+--------------------------------------------+
| Variable_name | Value                                      |
+---------------+--------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
1 row in set (0.00 sec)
 mysql> set @@sql_mode=ANSI;
 Query OK, 0 rows affected (0.00 sec)

 mysql> show variables like sql_mode;
 +---------------+-------------------------------------------------------------+
 | Variable_name | Value                                                       |
 +---------------+-------------------------------------------------------------+
 | sql_mode      | REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI |
 +---------------+-------------------------------------------------------------+
 1 row in set (0.00 sec)

这是设置之后的sql_mode.然后我们建立表格插入数据.

mysql> create table tt(name varchar(4), pass varchar(4));
Query OK, 0 rows affected (0.09 sec)

mysql> 
mysql> insert into tt values(aaaaa,aaaaa),(bbbb,bbbb);
Query OK, 2 rows affected, 2 warnings (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 2

mysql> show warnings;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column name at row 1 |
| Warning | 1265 | Data truncated for column pass at row 1 |
+---------+------+-------------------------------------------+
2 rows in set (0.00 sec)
mysql> select * from tt;
+------+------+
| name | pass |
+------+------+
| aaaa | aaaa |
| bbbb | bbbb |
+------+------+
2 rows in set (0.00 sec)

这时候发现数据可以插入成功,只是产生了2条waring数据,数据也被截取过了。

上面的是插入对应相同列的数据,我们再试下只插入一列数据的情况

mysql> insert into tt(name) values(eeee),(2eeee);
Query OK, 2 rows affected, 1 warning (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 1
mysql> show warnings;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column name at row 2 |
+---------+------+-------------------------------------------+
1 row in set (0.00 sec)
mysql> select * from tt;
+------+------+
| name | pass |
+------+------+
| aaaa | aaaa |
| bbbb | bbbb |
| eeee | NULL |
| 2eee | NULL |
+------+------+
4 rows in set (0.00 sec)

如果我们只设置了第一列name的value,而且另外一个列pass并没有设置为allow null的情况下,数据也是可以插入成功的。但是也有2条warning,而且数据也是被截取过的。

那接下来我们设置STRICT_TRANS_TABLES模式:

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

mysql> show variables like sql_mode;
+---------------+---------------------+
| Variable_name | Value               |
+---------------+---------------------+
| sql_mode      | STRICT_TRANS_TABLES |
+---------------+---------------------+
1 row in set (0.00 sec)

重复我们刚刚插入数据的方式

mysql> insert into tt values(aaaaa,aaaaa),(bbbb,bbbb);
ERROR 1406 (22001): Data too long for column name at row 1

发现SQL直接报错了,提示数据太长而不能插入.

修改数据插入

mysql> insert into test values(aaaa,aaaa),(bbbbb,bbbbb);
ERROR 1406 (22001): Data too long for column name at row 2
mysql> select * from test;
+------+------+
| name | pass |
+------+------+
| aaaa | aaaa |
| bbbb | bbbb |
| eeee | NULL |
| 2eee | NULL |
+------+------+
4 rows in set (0.00 sec)

发现数据都是插入不成功的。那我们再试试刚刚只插入1列数据的情况呢

mysql> insert test(name) value(wmq);
Query OK, 1 row affected (0.03 sec)

mysql> select * from test;
+------+------+-------+
| name | pass | value |
+------+------+-------+
| test |      |       |
| wmq  |      |       |
+------+------+-------+
2 rows in set (0.00 sec)

也是可以插入成功的,所以我可以自动,sql mode跟字段是否匹配没有关系。但是我们查看table info的create SQL可以发现,有的MySQL客户端

在建立表的时候,会给字段默认加上defalut ‘‘ 这个值,例如:

CREATE TABLE `test1` (
  `name` varchar(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `test2` (
  `name` varchar(4) NOT NULL DEFAULT ‘‘,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这是在我客户端和我同事的客户端上建表的create语句。有的客户端会让你选择default custom 有的会显示无默认值。但是我电脑的客户端就没有让你选择

default ‘‘的这个选项。技术分享

这点以后一定要非常注意,最好是统一使用相同的MySQL客户端或者干脆禁用远程账户,统一使用PMA或者命令行,这里有点偏题了

最后我们设置TRADITIONAL:

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

mysql> show variables like sql_mode;
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                                |
+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| 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)

发现和STRICT_TRANS_TABLES一样

 

mysql的sql_mode模式

标签:

原文地址:http://www.cnblogs.com/honeybaobao/p/4595505.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!