Mysql-sql_mode
2018-05-08 19:13
197 查看
一 、声明
二 、SQL_MODE参数值
三 、设置 sql_mode
1. SQL语法支持类
在5.7中默认启用,所以在实施5.6升级到5.7的过程需要注意:
2. 数据检查类
如果设置了严格模式,则 NO_ZERO_DATE 自然满足。但如果是 INSERT IGNORE 或 UPDATE IGNORE,'0000-00-00'依然允许且只显示warning
如果在非严格模式下,设置了
很多集成环境自带的MySQL貌似都没有开启MySQL的严格模式,何为MySQL的严格模式,简单来说就是MySQL自身对数据进行严格的校验(格式、长度、类型等),比如一个整型字段我们写入一个字符串类型的数据,在非严格模式下MySQL不会报错,同样如果定义了char或varchar类型的字段,当写入或更新的数据超过了定义的长度也不会报错。
我认为这个对于编程来说没有任何好处,虽然我们尽量在代码中做数据校验。MySQL开启了严格模式从一定程序上来讲是对我们代码的一种测试,如果我们的开发环境没有开启严格模式在开发过程中也没有遇到错误,那么在上线或代码移植的时候将有可能出现不兼容的情况,因此在开发过程做最好开启MySQL的严格模式。
注意
如果把 '' 传给int,严格模式下非法,若启用非严格模式则变成0,产生一个warning
Out Of Range,变成插入最大边界值
A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition
上面并没有囊括所有的 SQL Mode,选了几个代表性的,详细还是 看手册。
sql_mode一般来说很少去关注它,没有遇到实际问题之前不会去启停上面的条目。我们常设置的 sql_mode 是
相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
相当于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
无论何种mode,产生error之后就意味着单条sql执行失败,对于支持事务的表,则导致当前事务回滚;但如果没有放在事务中执行,或者不支持事务的存储引擎表,则可能导致数据不一致。MySQL认为,相比直接报错终止,数据不一致问题更严重。于是
5.6.6 以后版本默认就是
具体设置操作
二 、SQL_MODE参数值
三 、设置 sql_mode
一、 声明
原文:https://segmentfault.com/a/1190000005936172二 、SQL_MODE参数值
官方手册专门有一节介绍 https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html 。 SQL Mode 定义了两个方面:MySQL应支持的SQL语法,以及应该在数据上执行何种确认检查。1. SQL语法支持类
ONLY_FULL_GROUP_BY对于GROUP BY聚合操作,如果在SELECT中的列、HAVING或者ORDER BY子句的列,没有在GROUP BY中出现,那么这个SQL是不合法的。是可以理解的,因为不在 group by 的列查出来展示会有矛盾。
在5.7中默认启用,所以在实施5.6升级到5.7的过程需要注意:
Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column '1066export.ebay_order_items.TransactionID' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
ANSI_QUOTES启用 ANSI_QUOTES 后,不能用双引号来引用字符串,因为它被解释为识别符,作用与 ` 一样。设置它以后,
update t set f1="" ...,会报 Unknown column '' in 'field list 这样的语法错误。
PIPES_AS_CONCAT将
||视为字符串的连接操作符而非 或 运算符,这和Oracle数据库是一样的,也和字符串的拼接函数 CONCAT() 相类似。
NO_TABLE_OPTIONS使用
SHOW CREATE TABLE时不会输出MySQL特有的语法部分,如
ENGINE,这个在使用 mysqldump 跨DB种类迁移的时候需要考虑。
NO_AUTO_CREATE_USER字面意思不自动创建用户。在给MySQL用户授权时,我们习惯使用
GRANT ... ON ... TO dbuser顺道一起创建用户。设置该选项后就与oracle操作类似,授权之前必须先建立用户。5.7.7开始也默认了。
2. 数据检查类
NO_ZERO_DATE认为日期 '0000-00-00' 非法,与是否设置后面的严格模式有关。
如果设置了严格模式,则 NO_ZERO_DATE 自然满足。但如果是 INSERT IGNORE 或 UPDATE IGNORE,'0000-00-00'依然允许且只显示warning
如果在非严格模式下,设置了
NO_ZERO_DATE,效果与上面一样,'0000-00-00'允许但显示warning;如果没有设置
NO_ZERO_DATE,no warning,当做完全合法的值。
NO_ZERO_IN_DATE情况与上面类似,不同的是控制日期和天,是否可为 0 ,即
2010-01-00是否合法。
NO_ENGINE_SUBSTITUTION使用
ALTER TABLE或
CREATE TABLE指定 ENGINE 时, 需要的存储引擎被禁用或未编译,该如何处理。启用
NO_ENGINE_SUBSTITUTION时,那么直接抛出错误;不设置此值时,CREATE用默认的存储引擎替代,ATLER不进行更改,并抛出一个 warning .
STRICT_TRANS_TABLES设置它,表示启用严格模式。
很多集成环境自带的MySQL貌似都没有开启MySQL的严格模式,何为MySQL的严格模式,简单来说就是MySQL自身对数据进行严格的校验(格式、长度、类型等),比如一个整型字段我们写入一个字符串类型的数据,在非严格模式下MySQL不会报错,同样如果定义了char或varchar类型的字段,当写入或更新的数据超过了定义的长度也不会报错。
我认为这个对于编程来说没有任何好处,虽然我们尽量在代码中做数据校验。MySQL开启了严格模式从一定程序上来讲是对我们代码的一种测试,如果我们的开发环境没有开启严格模式在开发过程中也没有遇到错误,那么在上线或代码移植的时候将有可能出现不兼容的情况,因此在开发过程做最好开启MySQL的严格模式。
注意
STRICT_TRANS_TABLES不是几种策略的组合,单独指
INSERT、
UPDATE出现少值或无效值该如何处理:
如果把 '' 传给int,严格模式下非法,若启用非严格模式则变成0,产生一个warning
Out Of Range,变成插入最大边界值
A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition
上面并没有囊括所有的 SQL Mode,选了几个代表性的,详细还是 看手册。
sql_mode一般来说很少去关注它,没有遇到实际问题之前不会去启停上面的条目。我们常设置的 sql_mode 是
ANSI、
STRICT_TRANS_TABLES、
TRADITIONAL,ansi和traditional是上面的几种组合。
ANSI:更改语法和行为,使其更符合标准SQL
相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
TRADITIONAL:更像传统SQL数据库系统,该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。
相当于 STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
ORACLE:相当于 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER
无论何种mode,产生error之后就意味着单条sql执行失败,对于支持事务的表,则导致当前事务回滚;但如果没有放在事务中执行,或者不支持事务的存储引擎表,则可能导致数据不一致。MySQL认为,相比直接报错终止,数据不一致问题更严重。于是
STRICT_TRANS_TABLES对非事务表依然尽可能的让写入继续,比如给个"最合理"的默认值或截断。而对于
STRICT_ALL_TABLES,如果是单条更新,则不影响,但如果更新的是多条,第一条成功,后面失败则会出现部分更新。
5.6.6 以后版本默认就是
NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,5.5默认为 '' 。
三 、设置 sql_mode
查看#形式如 mysql> set sql_mode=''; mysql> set global sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'; #如果是自定义的模式组合,可以像下面这样 Adding only one mode to sql_mode without removing existing ones: mysql> SET sql_mode=(SELECT CONCAT(@@sql_mode,',<mode_to_add>')); Removing only a specific mode from sql_mode without removing others: mysql> SET sql_mode=(SELECT REPLACE(@@sql_mode,'<mode_to_remove>','')); #配置文件里面设置 sql-mode=""
具体设置操作
相关文章推荐
- MySQL 5.7.9版本sql_mode=only_full_group_by问题
- mysql 5.7.18版本 sql_mode 问题
- mysql SQL_MODE 参数作用
- mysql 插入默认值的问题 sql-mode
- MySQL::SQL_MODE
- mysql sql mode
- Mysql sql_mode设置 timestamp default 0000-00-00 00:00:00 创建表失败处理
- MySQL SQL mode
- [置顶] 关于mysql的sql_mode的问题
- MySQL错误:Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL easonjim
- 解决MySQL 5.7.9版本sql_mode=only_full_group_by问题
- mysql5.7 版本中 timestamp 不能为零日期 以及sql_mode合理设置
- mysql 1055错误的解决办法 【MYSQL5.7版本sql_mode=only_full_group_by问题】
- MySQL 5.7 sql_mode设置 分组查询报错
- MySQL 5.7.9版本sql_mode=only_full_group_by问题
- Mysql的SQL_MODE
- MYSQL - SQL_MODE
- mysql sql_mode 修改 排序分组查询
- Mysql SQL Mode详解
- mysql的sql_mode模式