示例一:
一个查询 select to_number(c.name) as srvtype, value as typename from sys_code c where c.srvclass=9 --srvclass为字符型
一直工作得很好,但突然一天返回错误ORA-01722 invalid number。由于条件srvclass字段是varchar2类型,就想当然地以为是ORACLE的bug(恰巧上周刚确认了ORACLE的一个查询bug),将条件改写成c.srvclass='9'后,查询就又能运行了。
事情虽然过去了,可总觉得有点不对劲。首先ORACLE不可能出现这么简单的BUG;其次就算是BUG,返回的错误提示也不应该是 invalid number。按理说,即使ORACLE不能自动完成类型转换而要求写成 srvclass='9',那么对srvclass=9这种写法的错误提示也应该是invalid character。但由于直觉作怪,也就没有深究
正好space6212提出了他对bug解释的疑问,我就从头进行检查,才发现错误的根本原因是:ORACLE将where c.srvclass=9解释为where to_number(c.srvclass)=9
1)以前执行SQL时,ORACLE进行全表扫描,对每行的srvclass都转换为number型进行比较.以前表中的srvclass的取值只有字符0到9,所以没有出错;
2)后来表中加入了新数据,srvclass的取值都是字母串,ORACLE进行全表扫描时,对新行上srvclass的to_number转换当然就返回ORA-01722 invalid number了。
示例二:
忽然有一天,好好的系统报错:ORA-01722 invalid number
环境:Oracle9 + JDBC访问数据库,之前是好的,忽然发现这个错误
后来参考了:http://davidyu720.itpub.net/post/31716/291191 才知道缘由
1. 代码里面执行了如下SQL语句:
select mdn from tablename where mdn=13800000000
tablename表里面的mdn字段是varchar2()类型字段,由于Oracle的字段类型隐式转换功能
上面的SQL语句通常是可行的,查询的时候oracle解析该条件时,会首先to_number(mdn)
再和where mdn=13812345678进行比较判断,如果能够确保mdn字段里面存放的全为数字
那么这个语句是一直不会报错的(可能存在效率问题),但偏偏有人误操作在mdn里面加入了
几个字母133aa000000,如果还是上面的语句,并且表里面没有13800000000这个用户的数据,
当查询扫描到133aa000000时to_number(mdn)报错ORA-01722 invalid number
2. 因此写SQL语句的时候最好还是规规矩矩的写:
select mdn from tablename where mdn='13800000000'
什么问题都没有!