一个优秀的程序都应该能够正确处理各种出错情况,并尽可能从错误中恢复。ORACLE 提供异常情况(EXCEPTION)和异常处理(EXCEPTION HANDLER)来实现错误处理。

有三种类型的异常错误

  • 预定义错误:ORACLE 预定于的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。
  • 非预定义错误:即其他标准的ORACLE 错误。对这种异常情况的处理,需要用户在程序中定义,然后由 ORACLE 自动将其引发。
  • 用户定义错误:程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用在程序中定义,然后显式地在程序中将其引发。

异常处理部分一般放在 PL/SQL 程序体的后半部,结构为:

EXCEPTION 
	WHEN first_exception THEN <code to handle first exception>
	WHEN second_exception THEN <code to handle second exception>
	WHEN OTHERS THEN <code to handle others exception>
END;

异常处理可以按任意次序排序,但 OTHERS 必须放在最后。

预定义的异常处理

freesql 查询异常 sql异常怎么解决_SQL


freesql 查询异常 sql异常怎么解决_异常错误_02

对这种异常情况的处理,只需要在 PL/SQL 块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。

示例

[预定义异常]
declare
  v_sal employees.salary%type;
begin
  select salary into v_sal
  from employees
  where employee_id >100;
  dbms_output.put_line(v_sal);

exception
  when Too_many_rows 
  	then dbms_output.put_line('输出的行数太多了');
end;

非预定义的异常处理
对于这类异常情况的处理,首先必须对非定义的 ORACLE 错误进行定义。步骤如下:

  • 在 PL/SQL 块的定义部分定义异常情况
<异常情况> EXCEPTION;
  • 将其定义好的异常情况,与标准的 ORACLE 错误联系起来,使用 PRAGMA EXCEPTION_INIT 语句:
PRAGMA EXCEPTION_INIT(<异常情况>,<错误代码>)
  • 在 PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

示例

[非预定义异常]
declare

  v_sal employees.salary%type;
  --声明一个异常
  delete_mgr_excep exception;
  --把自定义的异常和oracle的错误关联起来
  PRAGMA EXCEPTION_INIT(delete_mgr_excep,-2292);
begin
  delete from employees
  where employee_id = 100;
  
  select salary into v_sal
  from employees
  where employee_id >100;
  
  dbms_output.put_line(v_sal);

exception
  when Too_many_rows 
  	then dbms_output.put_line('输出的行数太多了');
  when delete_mgr_excep 
  	then dbms_output.put_line('Manager不能直接被删除');
end;

用户自定义的异常处理
当与一个异常错误相关的错误出现时,就会隐含触发该异常错误。用户定义的异常错误是通过显式使用 RAISE 语句来触发。当引发一个异常错误时,控制就转向到 EXCEPTION 块异常错误部分,执行错误处理代码。
对于这类异常情况的处理,步骤如下:

  • 1.在 PL/SQL 块的定义部分定义异常情况:
<异常情况> EXCEPTION;
  • RAISE <异常情况>
  • 在 PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

示例

[用户自定义异常]
declare

  v_sal employees.salary%type;
  --声明一个异常
  delete_mgr_excep exception;
  --把自定义的异常和oracle的错误关联起来
  PRAGMA EXCEPTION_INIT(delete_mgr_excep,-2292);
  
  --声明一个异常
  too_high_sal exception;
begin

  select salary into v_sal
  from employees
  where employee_id =100;
  
  if v_sal > 1000 then
     raise too_high_sal;
  end if;
     
  delete from employees
  where employee_id = 100;

  dbms_output.put_line(v_sal);

exception
  when Too_many_rows 
  	then dbms_output.put_line('输出的行数太多了');
  when delete_mgr_excep 
  	then dbms_output.put_line('Manager不能直接被删除');
  --处理异常
  when too_high_sal 
  	then dbms_output.put_line('工资过高了');
end;

异常的基本程序
通过 select … into … 查询某人的工资, 若没有查询到, 则输出 “未找到数据”

declare
  --定义一个变量
  v_sal employees.salary%type;
begin
  --使用 select ... into ... 为 v_sal 赋值
  select salary into v_sal 
  	from employees where employee_id = 1000;
  dbms_output.put_line('salary: ' || v_sal);
exception
  when No_data_found then 
       dbms_output.put_line('未找到数据');
end;
或
declare
  --定义一个变量
  v_sal employees.salary%type;
begin
  --使用 select ... into ... 为 v_sal 赋值
  select salary into v_sal from employees;
  dbms_output.put_line('salary: ' || v_sal);
exception
  when No_data_found then 
       dbms_output.put_line('未找到数据!');
  when Too_many_rows then 
       dbms_output.put_line('数据过多!');     
end;

更新指定员工工资,如工资小于300,则加100;对 NO_DATA_FOUND 异常, TOO_MANY_ROWS 进行处理.

declare
   v_sal employees.salary%type;
begin
   select salary into v_sal 
   	from employees where employee_id = 100;
   
   if(v_sal < 300) 
   	then update employees
   		 set salary = salary + 100 
   		 	where employee_id = 100;
   else dbms_output.put_line('工资大于300');
   end if;
exception
   when no_data_found 
   	then dbms_output.put_line('未找到数据');
    when too_many_rows 
    	then dbms_output.put_line('输出的数据行太多');
end;

处理非预定义的异常处理: "违反完整约束条件"

declare
  --1. 定义异常	
  temp_exception exception;
  --2. 将其定义好的异常情况,与标准的 ORACLE 错误联系起来,
  -- 使用 EXCEPTION_INIT 语句
  PRAGMA EXCEPTION_INIT(temp_exception, -2292);
begin
  delete from employees where employee_id = 100;

exception
  --3. 处理异常
  when temp_exception then
       dbms_output.put_line('违反完整性约束!');
end;

自定义异常: 更新指定员工工资,增加100;若该员工不存在则抛出用户自定义异常: no_result

declare
  --自定义异常                                   
  no_result exception;   
begin
  update employees 
  	set salary = salary + 100 
  		where employee_id = 1001;

  --使用隐式游标, 抛出自定义异常
  if sql%notfound then
     raise no_result;
  end if;  

exception

  --处理程序抛出的异常
  when no_result then
     dbms_output.put_line('更新失败');
end;