概述;pl/sql从数据表中向变量赋值,使用select into 子句,会带动来一些问题,如果查询没有记录时,会抛出no_data_found异常。如果有多条记录时,会抛出too_many_rows异常。
CREATE OR REPLACE PROCEDURE procexception (
p varchar2
)
AS
v_postype varchar2(20);
BEGIN
SELECT pos_type
INTO v_postype
FROM pos_type_tb1
WHERE 1 = 0;--为空,报no_data_found的错误
dbms_output.put_line(v_postype);
END;
解决方法:
一、no_data_found异常
1.直接加上异常处理。
CREATE OR REPLACE PROCEDURE procexception (
p varchar2
)
AS
v_postype varchar2(20);
BEGIN
SELECT pos_type
INTO v_postype
FROM pos_type_tb1
WHERE 1 = 0;
dbms_output.put_line(v_postype);
EXCEPTION
WHEN no_data_found THEN dbms_output.put_line("未找到数据");
END;
治标不治本,程序还是会中断。
2.select into做为一个独立的块,在这个块中进行异常处理
create or replace procedure procexception(
p varchar2
) as
v_postype varchar2(20);
begin
select pos_type into v_postype from pos_type_tb1 where 1=0;--为空
dbms_output.put_line(v_postype);
--其实吧,我觉得和上面那种差不多,原理一样的呀,no zuo nod ie
exception
when no_data_found then
v_postype := '';
end;
dbms_output.put_line(v_postype);
end;
3.使用游标
create or replace procedure proceexception(
p varchar2
) as
v_postype varchar2(20);
cursor c_postype is select pos_type from pos_type_tb1 where 1=0;
beign
if c_postype%found then
open c_postype;
fetch c_postype into v_postype;
close c_postype;
dbms_output.put_line(v_postype);
end if;
end;
二、too_many_rows异常
有两种情况:
1. 多条数据是可以接受的,也就是说从结果集中随便取一个值就行。这种情况应该很极端了吧,如果出现这种情况,也说明了程序的严谨性存在问题。
2. 多条数据是不可以被接受的,在这种情况肯定是程序的逻辑出了问题,也说是说原来根本就不会想到它会产生多条记录。
第一种情况解决方案:同no_date_found一样游标方式解决。
第二种解决方案:使用内部块解决。加上no_date_found 的处理。
create or replace proceduer procexception2(
p varchar2
) as
v_postype varchar2(20);
begin
begin
select pos_type into v_postype from pos_type_tb1 where rownum < 5;
exception
when no_data_found then
v_postype := null;
when too_many_rows then
raise_application_error(-20000,'对v_postype赋值是,找到多条数据');
end;
dbms_output.put_line(v_postype);
end;