令人抓狂的ORA-01722: 无效数字
某系统测试环境多个功能突然出现异常,排查后发现都是SQL无法正常运行,且错误都是“ORA-01722: 无效数字”,经过一次次排查,一次次确认,DS_STATE就是数字类型,为什么写查询SQL为DS_STATE字段赋数字类型报错,赋字符串类型却能正常执行。下文介绍了整个发现问题,分析问题到最后解决问题的过程。
在报错的所有语句中任意找了一条进行了排查,报错结果如下图:
确认DS_STATE到底是什么类型:
经过查看,DS_STATE就是数字类型。接着查看了视图YN_DAIRYSTATION_V 的内容,
从上图中看到 DS_STATE 与其他表字段在试图中做了关系,难不成问题在这儿,
接着查看了:bd_statu 表的ydb_pvalue 字段类型
\(^o^)/~,好像发现问题了,数字类型和字符串类型做了关联并且没有进行数据类型转换,但是,Oracle会进行自动隐式转换,应该不是这个问题,接着查看了正式环境数据库、开发环境数据库此语句都可以正常执行 ,所以确定不是类型转化的问题。
从SQL语句语法上分析没找到问题,后分析可能是数据库底层是不是做了什么设置导致SQL语句无法正常运行,有个这个想法请教了杨华峰老师,经过杨老师的分析后定位到
Oracle 初始化参数之cursor_sharing 惹的祸,目前系统设置cursor_sharing=FORCE,更改为为默认设置cursor_sharing= EXACT 后,所有报错的SQL都可以正常执行了。
总结经验,出现这个问题有两个解决办法:
第一种:在写多表关联的SQL语句时,where条件中的关联字段要做数据类型的显式转化,
改写前:
改写后:
或
第二种:调整 Oracle 初始化参数之cursor_sharing=EXACT
由于我运维的系统不是单个SQL有这个问题,是多个SQL都要同样的问题,所以我采用了第二种解决方法,以上就是我解决此问题的过程和方法,分享给大家,后续有同样的问题可以参考解决。