解决数据Incorrect DECIMAL value: ‘0’ for column ” at row -1问题

Incorrect DECIMAL value: ‘0’ for column ‘’ at row -1问题

场景:本来可以正常运行的系统,突然不能运行了。查看报错发现是如下。随手将错误信息一百度,结果被带到了沟里。网上的博客给出的解决方案多半是修改mysql配置。试了半天不行,回归分析问题,本来可以正常使用的代码突然不能用了,原因很可能是数据异常引起的代码问题,而不应该是环境层面,生产环境也不会轻易发生变化。而这个问题表达的意思也是数据转化的问题。

根本解法:对数据输入严格校验,避免出现cast转换值为null的情况,或者对于null的情况从逻辑上进行控制

错误代码

Cause: java.sql.SQLException: Incorrect DECIMAL value: '0' for column '' at row -1
; uncategorized SQLException for SQL []; SQL state [HY000]; error code [1366]; Incorrect DECIMAL value: '0' for column '' at row -1; nested exception is java.sql.SQLException: Incorrect DECIMAL value: '0' for column '' at row -1
	

正解

仔细检查数据,特别是使用cast(car_num AS DECIMAL) 函数转换的地方,表里发现car_num有一批新添加的数据为null,解决掉这批null数据,问题就解决了。

网上解法

在mysql配置文件my.cnf或my.ini中修改sql-mode。不过他们更多发生在数据迁移或者运维的场景下,的确会遇到数据库版本不一致的问题。

# Set the SQL mode to strict
sql-mode=”STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”
改为:
# Set the SQL mode to strict
sql-mode=”NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION”

去掉的参数的意义:

STRICT_TRANS_TABLES
针对insert,update,create table操作对于数据类型错误,不能为null等都会抛出错误,而对于查询一般只会警告。其实就是在null的情况下,不抛出错误,其实是一种自欺欺人的做法。

既然遇到了,顺手看一下MySQL的sql_mode模式

MySQL的sql_mode模式

mysql数据库的中有一个环境变量sql_mode,定义了mysql应该支持的sql语法,数据校验等。

key 说明
ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么将认为这个SQL是不合法的,因为列不在GROUP BY从句中
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过程中,如果被零除(或MOD(X,0)),则产生错误(否则为警告)。如果未给出该模式,被零除时MySQL返回NULL。如果用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操作结果为NULL。
NO_AUTO_CREATE_USER 防止GRANT自动创建新用户,除非还指定了密码。
NO_ENGINE_SUBSTITUTION 如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常。

mysql5.0以上版本支持三种sql_mode模式:

key 说明
ANSI模式 宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。
TRADITIONAL模式 严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事物时,会进行事物的回滚。
STRICT_TRANS_TABLES模式 严格模式,进行数据的严格校验,错误数据不能插入,报error错误。

MySQL 5.7 模式(SQL_MODE)详细说明

你可能感兴趣的:(数据库相关,问题解决)