MySQL关于sql_mode解析与设置讲解
昨晚在往mysql数据库中插入一组数据时,出错了!数据库无情了给我报了个错误:error 1365(22012):division by 0
;意思是说:你不可以往数据库中插入一个 除数为0的运算的结果。于是乎去谷歌了一番,总算是明白了其中的原因:是因为mysql的sql_mode 模式限制着一些所谓的‘不合法'的操作。
解析
这个sql_mode,简而言之就是:它定义了你mysql应该支持的sql语法,对数据的校验等等。。
如何查看当前数据库使用的sql_mode:
mysql> select @@sql_mode;
如下是我的数据库当前的模式:
mysql服务器能够工作在不同的sql模式下,并能针对不同的客户端以不同的方式应用这些模式。这样,应用程序就能对服务器操作进行量身定制以满足自己的需求。这类模式定义了mysql应支持的sql语法,以及应该在数据上执行何种确认检查。这样,就能在众多不同的环境下,与其他数据库服务器一起更容易地使用mysql。从mysql 4.1 开始,也能在启动之后,使用set[session|global]sql_mode='mode1,mode2…
'语句,通过设置sql_mode变量更改模式。
sql_mode常用值
only_full_group_by
对于group by聚合操作,如果在select中的列、having或者order by子句的列,没有在group by中出现,那么这个sql是不合法的。
对于不合法的sql语句,执行时会报如下错误
error 1055 (42000): expression #7 of select list is not in group by clause and contains nonaggregated column 'postscan.verifydelaylog.auditor' which is not functionally dependent on columns in group by clause; this is incompatible with sql_mode=only_full_group_by
no_auto_value_on_zero
该值影响自增长列的插入。默认设置下,插入0或null代表生成下一个自增长值。如果用户希望插入的值为0,该列又是自增长的,那么这个选项就有用了。
strict_trans_tables
在该模式下,如果一个值不能插入到一个事物表中,则中断当前的操作,对非事物表不做限制
no_zero_in_date
在严格模式,不接受月或日部分为0的日期。如果使用ignore选项,我们为类似的日期插入'0000-00-00'。在非严格模式,可以接受该日期,但会生成警告。
no_zero_date
在严格模式,不要将 '0000-00-00'做为合法日期。你仍然可以用ignore选项插入零日期。在非严格模式,可以接受该日期,但会生成警告。
error_for_division_by_zero
在insert或update过程中,如果数据被零除,则产生错误而非警告。如 果未给出该模式,那么数据被零除时mysql返回null
no_auto_create_user
禁止grant创建密码为空的用户
no_engine_substitution
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常
pipes_as_concat
将"||"视为字符串的连接操作符而非或运算符,这和oracle数据库是一样的,也和字符串的拼接函数concat相类似
ansi_quotes
启用ansi_quotes后,不能用双引号来引用字符串,因为它被解释为识别符
mysql5.0以上版本支持三种sql_mode模式:ansi、traditional和strict_trans_tables。
1、ansi模式:宽松模式,更改语法和行为,使其更符合标准sql。对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。对于本文开头中提到的错误,可以先把sql_mode设置为ansi模式,这样便可以插入数据,而对于除数为0的结果的字段值,数据库将会用null值代替。
2、traditional模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误,而不仅仅是警告。用于事物时,会进行事物的回滚。 注释:一旦发现错误立即放弃insert/update。如果你使用非事务存储引擎,这种方式不是你想要的,因为出现错误前进行的数据更改不会“滚动”,结果是更新“只进行了一部分”。
3、strict_trans_tables模式:严格模式,进行数据的严格校验,错误数据不能插入,报error错误。如果不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,如果值出现在单行语句或多行语句的第1行,则放弃该语句。
设置 sql_mode
查看当前连接会话的sql模式:
mysql> select @@session.sql_mode;
或者从环境变量里取
mysql> show variables like "sql_mode";
查看全局sql_mode设置:
mysql> select @@global.sql_mode;
设置global,需要重新连接进来才会生效
mysql> set global sql_mode='no_auto_create_user,no_engine_substitution,no_zero_date,no_zero_in_date';
设置全局sql_mode可以在不重启mysql的情况下生效
配置文件里面设置
sql_mode=no_auto_create_user,no_engine_substitution,no_zero_date,no_zero_in_date
修改配置文件后,重启mysql服务生效
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
上一篇: Docker部署Node.js的方法步骤