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)后一切都正常了。
写了这么多其实就是想说, 一定慎用隐式转换,这就好像是一颗定时炸弹。。
前天临下班,突然接到电话说网络报销系统预约报销功能出现问题,急需解决。琢磨一下。。最近好像没有功能更新,用了那么久怎么会突然不好使了呢,心想应该不是什么大问题,一会就能搞定。可是进入开发环境,看到错误代码我楞了一下。。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)后一切都正常了。
写了这么多其实就是想说, 一定慎用隐式转换,这就好像是一颗定时炸弹。。
相关文章推荐
- Related to Oracle SQL 关于选择前N行数据的SQL语句
- 关于ORACLE隐式转换后性能问题
- 关于执行Oracle下Sql语句中遇到的特殊字符问题解决办法。
- Related to Oracle SQL 关于Oracle大数据量处理与表分区
- 关于oracle多语言环境下to_date时间转换问题
- 今天在csdn上遇到一个问题,是关于sql数据行列转换的,我的写法如下:
- Oracle 关于number类型转换to_char类型 存在的问题
- Oracle关于varchar2型中"(空字符串)是否等于NULL问题
- Related to Oracle SQL 关于树形数据的遍历
- Related to Oracle SQL 关于优化,SQL语句的共享[笔记]
- Related to Oracle SQL 关于检验字符串是否为数字类型的方法
- 关于EXP-00056: 遇到 ORACLE 错误 1455 ORA-01455: 转换列溢出整数数据类型 EXP-00000: 导出终止失败 的问题解决方法整理
- Related to Oracle SQL 由Not in 引起取不到数据的错误
- 关于创建 LINQ to SQL 类时无法转换复数的问题(zhuan)
- php关于使用iconv(...)函数对字符进行中文转换时,遇到的一个问题
- Linq to SQL Delete时遇到问题的解决方法
- 安装Oracle SQL Developer时遇到的问题
- 关于PHPExcel中日期转换遇到的一些问题
- 数据库转换工具SqlServer To Oracle DbConvert
- golang关于json库的一个比较容易陷入的坑 uint8[]数组的json转换问题.