Datatruncation :Outofrangevalueforcolumnquanit 。。。
由于之前在⾃⼰电脑上搭建了mysql 5.6的数据库,但是在服务器上搭建的是mysql 5.7的环境,在运⾏过程中出现了如下错误:
Data truncation: Out of range value for column 'quanity' at row
1. 解决问题
问题索源由于安装的时候没有将关闭导致的
排查问题发现其中有解决问题将该字段去除即可
2. sql_mode 常⽤值说明
SQL 语法⽀持类
安装mysql失败对于GROUP BY 聚合操作,如果在SELECT 中的列、HAVING 或者ORDER BY ⼦句的列,没有在GROUP BY 中出现,那么这个SQL 是不合法的。是可以理解的,因为不在 group by 的列查出来展⽰会有⽭盾。
在5.7中默认启⽤,所以在实施5.6升级到5.7的过程需要注意:启⽤ ANSI_QUOTES 后,不能⽤双引号来引⽤字符串,因为它被解释为识别符,作⽤与 update t set f1="" ...`,会报 Unknown column ‘’ in ‘field
list 这样的语法错误。
将  视为字符串的连接操作符⽽⾮ 或 运算符,这和Oracle 数据库是⼀样的,也和字符串的拼接函数 CONCAT() 相类似
使⽤  时不会输出MySQL 特有的语法部分,如  ,这个在使⽤ mysqldump 跨DB 种类迁移的时候需要考虑。字⾯意思不⾃动创建⽤户。在给MySQL ⽤户授权时,我们习惯使⽤  顺道⼀起创建⽤户。设置该选项后就与oracle 操作类似,授权之前必须先建⽴⽤户。5.7.7开始也默认了。
数据检查类认为⽇期 ‘0000-00-00’ ⾮法,与是否设置后⾯的严格模式有关。
1.如果设置了严格模式,则 NO_ZERO_DATE ⾃然满⾜。但如果是 INSERT IGNORE 或 UPDATE IGNORE ,’0000-00-00’依然允许且只显⽰warning
2.如果在⾮严格模式下,设置了,效果与上⾯⼀样,’0000-00-00’允许但显⽰warning ;如果没有设置,no warning ,当做完全
合法的值。
3.情况与上⾯类似,不同的是控制⽇期和天,是否可为 0 ,即  是否合法。
使⽤ 或 指定 ENGINE 时, 需要的存储引擎被禁⽤或未编译,该如何处理。启⽤时,那么直接抛出
错误;不设置此值时,CREATE ⽤默认的存储引擎替代,ATLER 不进⾏更改,并抛出⼀个 warning .
设置它,表⽰启⽤严格模式。
注意  不是⼏种策略的组合,单独指 、出现少值或⽆效值该如何处理:
1.前⾯提到的把 ‘’ 传给int ,严格模式下⾮法,若启⽤⾮严格模式则变成0,产⽣⼀个warning
2.Out Of Range ,变成插⼊最⼤边界值
3.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 和traditional 是上⾯的⼏种组合。
:更改语法和⾏为,使其更符合标准SQL
相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
:更像传统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
:相当于 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS,
NO_AUTO_CREATE_USER
⽆论何种mode ,产⽣error 之后就意味着单条sql 执⾏失败,对于⽀持事务的表,则导致当前事务回滚;但如果没有放在事务中执⾏,或者不⽀持事务的存储引擎表,则可能导致数据不⼀致。MySQL 认为,相⽐直接报错终⽌,数据不⼀致问题更严重。于是  对⾮事务表依然尽可能的让写⼊继续,⽐如给个”最合理”的默认值或截断。⽽对于 ,如果是单条更新,则不影响,但如果更新的是多条,第⼀条成功,后⾯失败则会出现部分更新。
5.6.6 以后版本默认就是,5.5默认为 ‘’ 。
3. 设置 sql_mode
查看
STRICT_TRANS_TABLES show variables like "sql_mode";
STRICT_TRANS_TABLES
set sql_mode='NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
ONLY_FULL_GROUP_BY
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
⼀样。 设置它以后,PIPES_AS_CONCAT
||NO_TABLE_OPTIONS
SHOW CREATE TABLE ENGINE NO_AUTO_CREATE_USER
GRANT ... ON ... TO dbuser NO_ZERO_DATE
NO_ZERO_DATE NO_ZERO_DATE NO_ZERO_IN_DATE 2010-01-00NO_ENGINE_SUBSTITUTION
ALTER TABLE CREATE TABLE NO_ENGINE_SUBSTITUTION STRICT_TRANS_TABLES
STRICT_TRANS_TABLES INSERT UPDATE ANSI STRICT_TRANS_TABLES TRADITIONAL ANSI TRADITIONAL ORACLE STRICT_TRANS_TABLES STRICT_ALL_TABLES NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 查看当前连接会话的sql 模式:
mysql> select @@session.sql_mode;
或者从环境变量⾥取
mysql> show variables like "sql_mode";
设置配置⽂件⾥⾯设置 。
⼀个有趣的试验
updated: 2017-12-10
现⽹做数据迁移测试时报另⼀个错误,原由是这样的:⼀个1.8亿的表⾥⾯,因为某种原因需要把字段定义null 改为not null ,避免下游服务(如ES )处理特殊数据时异常情况。但这是⼀个并发dml ⾮常⾼⼜达到100多G 的⼤表,online ddl 针对这种修改字段类型简直束⼿⽆策,pt-osc 也慢的很。
刚好有⼀个做数据迁移的契机,原本打算在新库上把字段改好,再通过dts 或类似的数据迁移⼯具,同步过去。在⾮严格模式下,原本是null 的值也会变成0或’’,但还是报错了:到官⽅⽂档上的原话,可以解释:
If you are not using strict mode, then whenever you insert an “incorrect” value into a column, such as a NULL into a NOT NULL column or a too-large numeric value into a numeric column, MySQL sets the column to the “best possible value” instead of producing an error
If you try to store NULL into a column that doesn’t take NULL values, an error occurs for single-row INSERT statements. For multiple-row INSERT statements or for INSERT INTO … SELECT statements, MySQL Server stores the implicit default value for the column data type
⾮严格模式下,单⾏插⼊ null 到 not null 列,会失败;多⾏插⼊则只是warning 。规则是这样,也就⽆需解释。查看全局sql_mode 设置:
mysql> select @@global.sql_mode;
只设置global ,需要重新连接进来才会⽣效
形式如
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=""set sql_mode='';  -- 置为⾮严格模式
insert into t(id, a) values(1, null);
[Err] 1048 - Column 'a' cannot be null
然⽽
insert into t(id, a) values(1, null),(2, null),;
Affected rows: 2

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。