一、问题复现
有一张表中某个字段number为char类型,但实际在用where number= ?时,传入的参数为long类型,这样导致了mysql错误
异常堆栈信息如下:
org.springframework.dao.DataIntegrityViolationException: ### Error updating database. Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Truncated incorrect DOUBLE value: 'iot_account ' ### The error may involve cn.susoncloud.wisdomclass.usercenter.domain.repository.UserMapper.update-Inline ### The error occurred while setting parameters ### SQL: UPDATE user SET password=?, update_user_id=?, update_user_name=?, update_time=? WHERE number= ? ### Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Truncated incorrect DOUBLE value: 'iot_account ' ; ]; Data truncation: Truncated incorrect DOUBLE value: 'iot_account '; nested exception is com.mysql.jdbc.MysqlDataTruncation: Data truncation: Truncated incorrect DOUBLE value: 'iot_account ' at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:104) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446) at com.sun.proxy.$Proxy103.update(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294) at com.baomidou.mybatisplus.core.override.PageMapperMethod.execute(PageMapperMethod.java:73) at com.baomidou.mybatisplus.core.override.PageMapperProxy.invoke(PageMapperProxy.java:64) at com.sun.proxy.$Proxy112.update(Unknown Source) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.update(ServiceImpl.java:221) at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl$$FastClassBySpringCGLIB$$76535273.invoke(<generated>)
二、原因分析:
当字段类型实际为char,但传入的值却为long时,从mysql行为验证来看,mysql会将表中的该列值全部转换为数值类型,然后再去where匹配,然而如果列值中存在如“abc”这样的值,显然是没有办法转成数值类型的,所以就报了“ Truncated incorrect DOUBLE value”这样的错误。
如果列值都为“123”等这样的数值字符表示的值,都是可以转换成功的,是不会报错的。当然如果我们where 条件 属性值匹配时参数传递的与实际表中列值属性相同,这里如where number = “123”而不是where number = 123,那么也不会报错,因为类型相同,mysql不会进行类型转换,
也就不会出现转换的错误。
除了这种原因外,会导致这种错误。还有一种经常出现的错误情况:
update tab set name = ? , sex = ? where id = ?
却写成了
update tab set name = ? and sex = ? where id = ?
那么也会导致“ Truncated incorrect DOUBLE value”这样的错误。
其实,究其根本,从官方bug单中可以找到这一“bug”(https://bugs.mysql.com/bug.php?id=63112)单子中开发者example非常详细,会发现导致这一错误的出现,是因为mysql sql_mode默认值导致的,默认遵循严格的语法,当出现问题时,会error,如果采取非严格的sql_mode 级别,就不会抛出error,仅仅是warn了,正常执行了。对于类型转换,是mysql自身的策略,它会转成转换双精度值。
三、参考
参考 可能导致的错误类型:
https://stackoverflow.com/questions/3456258/mysql-truncated-incorrect-double-value
参考 mysql官方bug:
https://bugs.mysql.com/bug.php?id=63112
参考 mysql sql_mode 解读:
向5S进行回复 取消回复