select count(*) into 也会报 NO_DATA_FOUND 异常?!
2011-11-25 10:45
274 查看
From: http://www.cnblogs.com/howelei/archive/2006/12/21/599268.html
我们知道NO_DATA_FOUND异常情况仅仅被SELECT..INTO语句触发,当该WHERE子句没有找到任何行的时候就会触发它。
解决的方法通常有两种:
一种是我们将查询语句写成游标,这样WHERE子句没有找到任何行的时候, SQL%NOTFOUND就会设置成TRUE,而不会报NO_DATA_FOUND;
还有一种是我们在查询前先SELECT COUNT(*) INTO 一下,看看WHERE子句是否能找到相应的行,如果有再SELECT..INTO。
第二种方法虽然效率上有消耗,但是简单易写,因此我们在写存储过程时经常使用。
但是,大家试着测试下面的存储过程:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
create or replace procedure A_TEST1 is
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
n_num number;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
begin
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
select count(*)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
into n_num
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
from mascty
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
where mascty.mctcty = '123'
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
group by mascty.mctcty;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
end A_TEST1;
结果令人吃惊啊,这种偏偏是为了避免产生 NO_DATA_FOUND 异常的SELECT COUNT(*) INTO语句也会产生NO_DATA_FOUND 异常。
原因在哪呢?
从代码上看SELECT COUNT(*) INTO语句最后跟了group by。编程人员意思可能是将查询的结果,根据group by的条件分组,然后,再COUNT看一共有多少个组。
其实这种理解是错误的。这个查询真正的顺序是先将查询的结果COUNT,然后再group by。如果查询的结果COUNT为0,即没有符合条件的结果,再group by,那么返回的就不是0,而是空(NULL)。
所以将一个空值放到一个整型的变量中就会产生NO_DATA_FOUND的异常。
如何解决呢?
按照编程者真正的目的将存储过程改为:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
create or replace procedure A_TEST1 is
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
n_num number;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
begin
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
select count(*)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
into n_num
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
from (select *
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
from mascty
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
where mascty.mctcty = '123'
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
group by mascty.mctcty);
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
end A_TEST1;
这样COUNT出来的值就是0,也是想要的结果,不会产生NO_DATA_FOUND 异常。
总结:
1.一定要注意在使用group by时,SELECT COUNT(*) INTO语句也会产生NO_DATA_FOUND 异常。
2.一定要理解好group by执行的顺序。
我们知道NO_DATA_FOUND异常情况仅仅被SELECT..INTO语句触发,当该WHERE子句没有找到任何行的时候就会触发它。
解决的方法通常有两种:
一种是我们将查询语句写成游标,这样WHERE子句没有找到任何行的时候, SQL%NOTFOUND就会设置成TRUE,而不会报NO_DATA_FOUND;
还有一种是我们在查询前先SELECT COUNT(*) INTO 一下,看看WHERE子句是否能找到相应的行,如果有再SELECT..INTO。
第二种方法虽然效率上有消耗,但是简单易写,因此我们在写存储过程时经常使用。
但是,大家试着测试下面的存储过程:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
create or replace procedure A_TEST1 is
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
n_num number;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
begin
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
select count(*)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
into n_num
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
from mascty
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
where mascty.mctcty = '123'
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
group by mascty.mctcty;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
end A_TEST1;
结果令人吃惊啊,这种偏偏是为了避免产生 NO_DATA_FOUND 异常的SELECT COUNT(*) INTO语句也会产生NO_DATA_FOUND 异常。
原因在哪呢?
从代码上看SELECT COUNT(*) INTO语句最后跟了group by。编程人员意思可能是将查询的结果,根据group by的条件分组,然后,再COUNT看一共有多少个组。
其实这种理解是错误的。这个查询真正的顺序是先将查询的结果COUNT,然后再group by。如果查询的结果COUNT为0,即没有符合条件的结果,再group by,那么返回的就不是0,而是空(NULL)。
所以将一个空值放到一个整型的变量中就会产生NO_DATA_FOUND的异常。
如何解决呢?
按照编程者真正的目的将存储过程改为:
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
create or replace procedure A_TEST1 is
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
n_num number;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
begin
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
select count(*)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
into n_num
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
from (select *
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
from mascty
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
where mascty.mctcty = '123'
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
group by mascty.mctcty);
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
end A_TEST1;
这样COUNT出来的值就是0,也是想要的结果,不会产生NO_DATA_FOUND 异常。
总结:
1.一定要注意在使用group by时,SELECT COUNT(*) INTO语句也会产生NO_DATA_FOUND 异常。
2.一定要理解好group by执行的顺序。
相关文章推荐
- 【原创】select count(*) into 也会报 NO_DATA_FOUND 异常?!
- ORACLE SELECT INTO NO_DATA_FOUND问题
- ORACLE SELECT INTO NO_DATA_FOUND问题
- ORACLE SELECT INTO NO_DATA_FOUND问题
- NO_DATA_FOUND SQL%NOTFOUND、SQL%ROWCOUNT的区别
- oracle select 【列名】 into 【变量】 NO_DATA_FOUND 问题
- oracle 中的 no_data_found异常 含义
- 【原创】Oracle函数中对于NO_DATA_FOUND异常处理的研究
- Oracle数据库疑问:函数出现no_data_found不报异常
- ORA-01403:no data found 及 select a into b 空值
- 避免selet into的no_data_found
- oracle异常之no_data_found
- 170524、java.lang.IllegalArgumentException: No converter found for return value of type异常解决
- [异常]No ValidatorAction named required found for field name
- FSG报表打印报错,log文件显示java.sql.SQLException: No corresponding LOB data found
- spring-data-elasticsearch查询No property ... found for...Did you mean '...'?
- springMVC 使用ajax 出现No serializer found for class异常
- no_data_found的解决方法
- SSH整合开发之异常:No Session found for current thread
- ORA-01403:no data found 解决办法