SQL_MODE设置
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 |
转载于:https://blog.51cto.com/gfsunny/1585353
SQL_MODE设置相关推荐
- 创建mysql的表怎么显示00_Mysql sql_mode设置 timestamp default 0000-00-00 00:00:00 创建表失败处理...
往数据库里创建新表的时候报错: [Err] 1067 - Invalid default value for 'updateTime' DROP TABLE IF EXISTS `passwd_res ...
- MySQL sql_mode设置
因为sql_mode设置的不同可能会出现有些SQL在一个实例可以执行,在另一个实例却不能执行.下面就记录下不同sql_mode的特点: 查看sql_mode SELECT @@GLOBAL.sql_m ...
- MySQL高级篇01【字符集、SQL规范和sql_mode设置】
目录 1. 字符集操作 1.1 修改MySQL5.7字符集 1. 修改步骤 2.已有库/表字符集的变更 1.2 字符集级别分类 1. 服务器级别 2. 数据库级别 3. 表级别 4. 列级别 5. 小 ...
- mysql 5.7 sql_mode设置 坑
1.查看sql_mode select @@sql_mode 查询出来的值为: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZE ...
- mysql 设置宽松模式_mysql5.6 sql_mode设置为宽松模式
最近遇到一个很奇怪的事情 由于数据人员的需求,现在需要修改mysql的sql_mode sql_mode默认是sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_ ...
- mysql 改成宽松模式_mysql5.6 sql_mode设置为宽松模式
最近遇到一个很奇怪的事情 由于数据人员的需求,现在需要修改mysql的sql_mode sql_mode默认是sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_ ...
- mysql 1264_关于MySQL的1264错误处理及sql_mode设置
MySQL升级到5.0.17后,在执行sql语句 insert INTO `表名` ( ) VALUES ( ); 时出现错误: #1264 – Out of range value for colu ...
- SQL_MODE设置之ansi_quotes
今天做项目,一个sql语句 原本是用字符串拼接的,参考如下: 'SELECT COUNT(DISTINCT mac,diskid,systeminstalltime) as total_uv, CO ...
- mysql命令行设置sqlmodel_MySQL的sql_mode模式说明及设置
一.MySQL的sql_mode合理设置 sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模式, ...
最新文章
- Java调用C/C++编写的第三方dll动态链接库(zz)
- 如何用 Redis 解决海量重复提交问题
- Galaxy Release (v 21.05),众多核心技术栈变更
- 【Flutter】Dart 函数 ( 函数构成 | 私有函数 | 匿名函数 | 函数总结 )
- ASP.NET MVC – 关于Action返回结果类型的事儿(上)
- vue element 框架 自定义轮播图,点击上下翻图,并让图片居中
- 【公益】开放一台Eureka注册中心给各位Spring Cloud爱好者
- python 历遍子弹_python之子弹移动
- beego 例子_beego框架代码分析
- javax maven项目缺少_maven冲突解决流程
- 计算机word实训项目任务说明,计算机项目实训报告怎么写啊
- Axios中无法运行 json-server【已解决】
- ROC曲线和AUC 原理与实现——Python实战
- Java 二分排序法
- Perl脚本使用小总结
- Delphi 实现多国语言
- 7、万国觉醒建筑白天黑夜效果(Shader Graph)
- html圣诞效果,HTML5实现圣诞树效果
- 安全多方学习开源框架调研
- git 拉取指定的远程分支(三种方式)