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设置相关推荐

  1. 创建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 ...

  2. MySQL sql_mode设置

    因为sql_mode设置的不同可能会出现有些SQL在一个实例可以执行,在另一个实例却不能执行.下面就记录下不同sql_mode的特点: 查看sql_mode SELECT @@GLOBAL.sql_m ...

  3. MySQL高级篇01【字符集、SQL规范和sql_mode设置】

    目录 1. 字符集操作 1.1 修改MySQL5.7字符集 1. 修改步骤 2.已有库/表字符集的变更 1.2 字符集级别分类 1. 服务器级别 2. 数据库级别 3. 表级别 4. 列级别 5. 小 ...

  4. mysql 5.7 sql_mode设置 坑

    1.查看sql_mode select @@sql_mode 查询出来的值为: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZE ...

  5. mysql 设置宽松模式_mysql5.6 sql_mode设置为宽松模式

    最近遇到一个很奇怪的事情 由于数据人员的需求,现在需要修改mysql的sql_mode sql_mode默认是sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_ ...

  6. mysql 改成宽松模式_mysql5.6 sql_mode设置为宽松模式

    最近遇到一个很奇怪的事情 由于数据人员的需求,现在需要修改mysql的sql_mode sql_mode默认是sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_ ...

  7. mysql 1264_关于MySQL的1264错误处理及sql_mode设置

    MySQL升级到5.0.17后,在执行sql语句 insert INTO `表名` ( ) VALUES ( ); 时出现错误: #1264 – Out of range value for colu ...

  8. SQL_MODE设置之ansi_quotes

    今天做项目,一个sql语句  原本是用字符串拼接的,参考如下: 'SELECT COUNT(DISTINCT mac,diskid,systeminstalltime) as total_uv, CO ...

  9. mysql命令行设置sqlmodel_MySQL的sql_mode模式说明及设置

    一.MySQL的sql_mode合理设置 sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模式, ...

最新文章

  1. Java调用C/C++编写的第三方dll动态链接库(zz)
  2. 如何用 Redis 解决海量重复提交问题
  3. Galaxy Release (v 21.05),众多核心技术栈变更
  4. 【Flutter】Dart 函数 ( 函数构成 | 私有函数 | 匿名函数 | 函数总结 )
  5. ASP.NET MVC – 关于Action返回结果类型的事儿(上)
  6. vue element 框架 自定义轮播图,点击上下翻图,并让图片居中
  7. 【公益】开放一台Eureka注册中心给各位Spring Cloud爱好者
  8. python 历遍子弹_python之子弹移动
  9. beego 例子_beego框架代码分析
  10. javax maven项目缺少_maven冲突解决流程
  11. 计算机word实训项目任务说明,计算机项目实训报告怎么写啊
  12. Axios中无法运行 json-server【已解决】
  13. ROC曲线和AUC 原理与实现——Python实战
  14. Java 二分排序法
  15. Perl脚本使用小总结
  16. Delphi 实现多国语言
  17. 7、万国觉醒建筑白天黑夜效果(Shader Graph)
  18. html圣诞效果,HTML5实现圣诞树效果
  19. 安全多方学习开源框架调研
  20. git 拉取指定的远程分支(三种方式)

热门文章

  1. 利用OracleCommandBuilder实现 datatable与数据库的增删改
  2. Gerrit代码审核服务器搭建全过程
  3. 【转载】如何组建一支优秀的数据分析团队?
  4. git配置服务器版仓库
  5. 关于静态类初始化问题----CSharp
  6. 「产品规划」的那些事儿
  7. 微信的充值页面为啥长这样?(多图)
  8. C# SqlBulkCopy数据批量入库
  9. C/C++练习题(一)
  10. python单元测试之unittest框架使用