一 ,no_data_found异常的触发
oracle编程中 select into 语句没有记录时,会触发no_data_found异常
二,no_data_found异常解决方法
如果在一个程序块中,发生异常程序就会停止执行,报出异常。如果我们不想让程序因为这个no_data_found异常而停止执行,可以用如下方法
1)用子块来处理
把会报出no_data_found异常的select into语句放到一个子块中
declare
sal1 number;
sal2 number;
sal3 number;
begin
select sal into sal1 from emp1 where empno=7369;
begin
select sal into sal2 from emp1 where empno=1;
exception
/* when no_data_found then
sal2:=2500;*/
when others then
dbms_output.put_line(sqlcode||':'||sqlerrm);
end;
select sal into sal3 from emp1 where empno=7499;
dbms_output.put_line('工号:'||7369||'——'||'工资:'||sal1);
dbms_output.put_line('工号:'||1||'--'||'工资;'||sal2);
dbms_output.put_line('工号:'||7499||'--'||'工资:'||sal3);
exception
when others then
dbms_output.put_line(sqlcode||':'||sqlerrm);
end;
如上面这一段代码中第二个select into 语句执行时会报no_data_found异常,我们把他放到一个子块里面,字块报异常以后程序还可以继续执行,不会影响其他部分。
2)用nvl函数结合聚合函数来处理
declare
tem number;
no_data exception;
begin
select nvl(max(sal),-1) into tem from emp1 where empno=1;
/* insert into emp1 select * from emp t where t.empno=1;
if sql%notfound then
dbms_output.put_line(sql%rowcount);
dbms_output.put_line('sql语句没有匹配项');
raise no_data;
end if;*/
dbms_output.put_line(tem);
exception
when no_data then
raise_application_error(-20006,'没有发现数据');
end;
注意:如果该处不用聚合函数直接写成select max(sal) into tem from emp1 where empno=1;
那么还是会报no_data_found异常,至于原因下文会详细解释。
3)在select inot 之前先作一下判断
select count(1) into tem from emp where empno=1;
如果等于1的时候 select into语句可以正常执行,等于0 会报no_data_found错,大于1会报too_many_rows
4)用事务自治
oracle自治事务相关知识以后再作了解。
三,no_data_found异常同聚合函数
注意 语句有使用聚合函数时一般不会报no_data_found错(但也有例外,同group by一起使用时),
原因如下:
这里就涉及到 有一条记录但是记录是空记录 和没有一条记录 的问题了。 首先弄清楚no data found异常是在找不到一条记录的时候报的异常,但是在找到一条空记录的时候是不会报这个异常的。 用集合函数之所以不会报错原因是: 用集合函数的时候,当参数没有赋值时,函数会默认赋一个空值来进行计算,返回的结果也是一个空值(不是没有值)。 而to_char、substr这些函数就不会当参数没有赋值时默认赋空值,也就没有结果返回。 所以区别就是一个有记录返回,但是个空记录,而一个是没有记录返回。 其实你要看清楚空记录和没有记录的区别可以执行如下的程序看返回结果的差别就懂了。 OPEN OUTCURSOR FOR select MAX(t.Time) from dept t where t.id>'10'; 比较 OPEN OUTCURSOR FOR select t.Time from dept t where t.id>'10'; 再比较 OPEN OUTCURSOR FOR select to_char(t.Time,'yyyy-mm-dd') from dept t where t.id>'10';
但是也有例外,就是使用了聚合函数,还是报了no_data_found
select sum(sal) from into sal1 emp1 where empno=1 group by empno;(注意group by的使用)
下面的连接是我搜到的关于group by使用报no_data_found错误的解释(个人感觉说的有点问题,仅供参考!)