最近遇到一个报错的sql语句:
select ... from xxx where ... and v.ATTR_VALUE = 1
执行报错:
ORA-01722: invalid number
最终发现是where条件中ATTR_VALUE值为数字类型,而实际上ATTR_VALUE字段为字符类型,所以在隐式转换的时候又字符串转换为数字的时候出错了。但是在MySQL中执行正常。最终将mysql和oracle版中的sql语句统一改为:
select ... from xxx where ... and v.ATTR_VALUE = '1'
故在此总结一些mysql和oracle中的隐式转换问题。
隐式转换主要包括数字和字符、日期时间之间的转换。这里主要总结下数字和字符转换问题。
Mysql:
1.where条件为数字,字段为字符串
会将字符串转为数字进行比较。例如:
表user:
name age(字符串类型)
aa '18'
bb '20'
语句:
select * from user where age=18
实际上在执行过程中,会将每一条记录的age字段都先转化为数字,再和where条件比较。
转换原则:
从左到右依次匹配数字,直到匹配到非数字为止。如果第一位就不是数字则返回0
例如:
select cast('11a' as unsigned int)
输出:11
select cast('a11a' as unsigned int)
输出:0
2.where条件为字符串,字段为数字
同样的,会将字符串转化为数字。转换原则和上边的相同。
表user:
name age(数字类型)
aa 18
bb 20
语句:
select * from user where age='18'
实际上在执行过程中把wehre条件中的18转为了‘18’,作为一个字符串和字段age比较。
Oracle:
1.where条件为数字,字段为字符串
和MySQL一样,任然是把字符转为数字,只是Oracle中如果字符串中包含非数字字符则会报错,转换不成功,而不会从从左往右截取出数字。
2.where条件为字符串,字段为数字
同样是字符转数字。
问题:
为什么遇到数字和字符转换的时候都是字符转数字而不是数字转字符呢?
引用一段话:
如果是数字往字符去转换,如 0 转’0’,这样查询出来的结果只能是字段等于 ‘0’,而实际上,表里的数据,如’a0’,‘00’,这其实都是用户想要的0,毕竟是用户指定了数字0,所以MySQL还是以用户发出的需求为准,否则,'00’这些都不会返回给用户作者:JackpGao
链接:https://www.jianshu.com/p/6f34e9708a80
所以,一方面为了保证程序不出错,另一方面保证数据库效率,尽量在sql语句中的字段类型与表中的字段类型一致。
以上,如有遗漏或不正确的地方,望大家指正。