ORA-01403: 未找到任何数据

2016/05/02 12:11
阅读数 1.9W

1. 存储过程中 ORA-01403: no data found 错误

在存储过程中,select 字段名  into  变量 from 表名 where .........;

如果查询出来为空时, 会出现  ORA-01403: no data found 的错误

测试表:

[sql] view plain copy

  1. create table TEST_TABLE  

  2. (  

  3.   T_ID   NUMBER,  

  4.   T_NAME VARCHAR2(20)  

  5. ) ;  

测试存储过程:

[sql] view plain copy

  1. create or replace procedure pro_test is  

  2. v_id test_table.t_id%type;  

  3. begin  

  4.   select t_id into v_id from test_table where rownum = 1;  

  5. end pro_test;  

错误:









2. 解決办法:

造成错误的原因主要是数据库中没有对应的数据。而当直接使用该查询语句时,是不会报错的,返回0记录。

2.1. 对查询字段使用聚合函数

增加一个min函数。这主要是因为聚合函数没有找到数据时,会返回0,而不是null。

存储过程改为:

[sql] view plain copy

  1. create or replace procedure pro_test is  

  2. v_id test_table.t_id%type;  

  3. begin  

  4.   select min(t_id) into v_id from test_table where rownum = 1;  

  5. end pro_test;  


这些主要是聚合类型的函数,如sum,count,max,min等。其的函数则不行,如to_char,substr.

另外,如使用nvl,即

[sql] view plain copy

  1. select nvl(t_id,1) into v_id from test_table where rownum = 1;  

是没效果的,还是会报异常。nvl只对null值处理,而select t_id into  v_id from table是返回空记录。

缺点:1. 使用集合函数后可能偏离你所需要查找的值;2. 在数据量比较大时,这种方法明显会降低效率。

参考:oracle 中使用 select a into b 时遇到空值问题

2.2. 使用异常处理

即加入异常处理

[sql] view plain copy

  1. create or replace procedure pro_test is  

  2. v_id test_table.t_id%type;  

  3. begin  

  4.   select t_id into v_id from test_table where rownum = 1;  

  5.   exception  

  6.     when no_data_found then -- no_data_found 也可以换成 others  

  7.       null;  --其它操作。。。  

  8. end pro_test;  

但加入异常处理后,当抛出异常,程序无法继续下面的语句。即我们不能从异常句柄再重新回到当前块。这时可以增加begin...end 模拟TRY..CATCH..块

[sql] view plain copy

  1. create or replace procedure pro_test is  

  2.   v_id test_table.t_id%type;  

  3. begin  

  4.   begin  

  5.     select t_id into v_id from test_table where rownum = 1;  

  6.   exception  

  7.     when no_data_found then  

  8.       -- no_data_found 也可以换成 others  

  9.       null--其它操作。。。  

  10.   end;  

  11.   insert into test_table values (1, 'test');  

  12. end pro_test;  


另外还有一个问题就是,当多个地方抛出同一个异常时,如果判别是哪条语句抛出的异常呢?

可以使用定位变量标记异常发生点。

[sql] view plain copy

  1. create or replace procedure pro_test is  

  2.   v_id test_table.t_id%type;  

  3.   stmt integer := 1;  

  4. begin  

  5.   select t_id into v_id from test_table where rownum = 1;  

  6.   stmt := 2;  

  7.   select t_id into v_id from test_table where rownum = 1;  

  8.   

  9. exception  

  10.   when no_data_found then    

  11.     insert into errors values ('Error statment', stmt);   

  12. end pro_test;  

参考:第七章 控制PL/SQL错误

2.3. 使用游标替代

[sql] view plain copy

  1. create or replace procedure pro_test is  

  2.   v_id test_table.t_id%type;  

  3.     

  4.   type cursor_type is ref cursor;  

  5.   cur cursor_type;  

  6. begin  

  7.   open cur for select t_id from test_table where rownum = 1;  

  8.   fetch cur into v_id;  

  9.   close cur;  

  10. end pro_test;  

博客转载:http://blog.csdn.net/hao123yao/article/details/8267352

参考:

http://blog.csdn.net/jojo52013145/article/details/6585833

http://www.verydemo.com/demo_c289_i18597.html


展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部