您的位置:首页 > 数据库 > Oracle

Related to Oracle SQL 关于遇到Number型与varchar2型比较时的隐式转换引起的生产问题

2011-05-13 17:16 549 查看
写了这么多其实就是想说, 一定慎用隐式转换,这就好像是一颗定时炸弹。。

前天临下班,突然接到电话说网络报销系统预约报销功能出现问题,急需解决。琢磨一下。。最近好像没有功能更新,用了那么久怎么会突然不好使了呢,心想应该不是什么大问题,一会就能搞定。可是进入开发环境,看到错误代码我楞了一下。。SQL错误,还是INVALID NUMBER..怎么可能啊。错误是一个存储过程运行中出现的,fetch 一个游标的时候报错。我打开了测试环境的数据库(跟正式环境是一样的配置),打开PLSQL,把那条被fetch的游标语句粘了上去,运行程序,加上断点,取得运行时存储过程需要的所有实时参数。扔到刚刚的游标语句后的WHERE 条件对应的变量中运行了一下。成功了。。我当时汗啊,怎么回事??我又把参数直接扔到存储过程TEST的窗口中,运行,居然也没有报错。只好接着连上正式的库,同样执行的这条语句,结果让我意外。。。也通过了。同样TEST了一下存储过程,存储过程又在那个fetch的时候报错了。奇怪啊。。单独执行cursor语句没有问题为什么fetch会报错呢。。上网搜了下,看到有写关于类型隐式转换可能会引起此问题,可是细看下跟我现在的情况有又不太相同,不过还是给我了一些启示。我看了一遍传入参数,存储过程变量的类型。发现游标语句中确实存在着隐式转换的情况。语句如下:

SELECT count(1)
FROM BXXXB

WHERE YYCK = V_CKH(V_CKH是存储过程中的变量,number型的,而YYCK字段是字符型的,存储的是窗口号)

AND TO_CHAR(RQ, 'YYYY-MM-DD') = '2011-05-12'
AND AMPM = 'AM';

看了下语句已经可以确定一定是YYCK= V_CKH这句报的错,当比较一个字符型和数值型的值时,oracle会把字符型的值隐式转换为数值型。如假设id列的数据类型为varchar2:
select * from t where id=1; 等同于 select * from t where to_number(id)=1

这么看来一定是这个隐式转换的to_number出现了问题,to_number报错那一定是这个字段中存在非数字型的数据,也可以解释为什么在测试环境可以跑通,但正式上不行了。可是正式环境中YYCK存放的是窗口号,一定都是数字应该不会出现非数字的窗口号,带着疑问我select了一下,select yyck from bxxxb where yyck is not null order by yyck; 结果让我很纳闷。使用条件is not null查询出的结果居然有一条数据是空着的,还不是空格,也就是这条数据导致存储过程抛出了异常。

心想以前写这存储过程的兄弟一定没有料到这个字段会出现这种数据。。最后把WHERE YYCK = V_CKH修改为了WHERE YYCK = to_char(V_CKH)后一切都正常了。

写了这么多其实就是想说, 一定慎用隐式转换,这就好像是一颗定时炸弹。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: