异常错误处理

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

①有三种类型的异常错误:

1. 提前定义( Predefined )错误

    ORACLE提前定义的异常情况大约有24个。对这样的异常情况的处理。无需在程序中定义,由ORACLE自己主动将其引发。

2. 非提前定义( Predefined )错误

    即其它标准的ORACLE错误。

对这样的异常情况的处理,须要用户在程序中定义,然后由ORACLE自己主动将其引发。

3. 用户定义(User_define) 错误

    程序运行过程中,出现编程人员觉得的非正常情况。对这样的异常情况的处理。须要用户在程序中定义,然后显式地在程序中将其引发。

②异常处理部分一般放在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 必须放在最后.

③提前定义的异常处理

对这样的异常情况的处理,仅仅需在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错误进行定义。

过程例如以下:

1. 在PL/SQL 块的定义部分定义异常情况:

<异常情况>  EXCEPTION;

2. 将其定义好的异常情况,与标准的ORACLE错误联系起来,使用PRAGMA EXCEPTION_INIT 语句:

PRAGMA EXCEPTION_INIT(<异常情况>, <错误代码>);

3. 在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;

2. RAISE <异常情况>。

3. 在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;

⑥在PL/SQL 中使用SQLCODE, SQLERRM

SQLCODE 返回错误代码数字

SQLERRM 返回错误信息.

EXCEPTION

WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE(SQLCODE||’---‘||SQLERRM);

⑦异常程序:

1.通过 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;

2. 更新指定员工工资,如工资小于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;

3. 处理非提前定义的异常处理: "违反完整约束条件"

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;

4. 自己定义异常: 更新指定员工工资,添加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;

PL/SQL 异常错误处理的更多相关文章

  1. oracle学习笔记(十六) PL/SQL 异常和goto语句

    PL/SQL 异常和goto语句 异常 预定义异常 oracle常见预定义异常: 错误号 异常错误信息名称 说明 ORA-0001 DUP_VAL_ON_INDEX 试图破坏一个唯一性限制 ORA-0 ...

  2. PL/SQL 异常处理程序

     异常处理程序 一个好的程序应该能够妥善处理各种错误情况,并尽可能从错误中恢复.ORACLE 提供异常(EXCEPTION)和异常处理(EXCEPTION HANDLER)错误处理 ①有三种类型的 ...

  3. Oracle PL/SQL异常、存储过程和触发器

    一.异常 1.处理异常 (1)除数不为0 declare b number; begin b:; exception when zero_divide then dbms_output.put_lin ...

  4. PL/SQL连接错误:ora-12705:cannot access NLS data files or invalid environment specified

    适合自己的解决方法: 排查问题: 1. 你没有安装Oracle Client软件.这是使用PL/SQL Developer的必须条件.安装Oracle Client后再重试.2. 你安装了多个Orac ...

  5. PL/SQL异常

    CASE_NOT_FOUND CASE selector WHEN selector_value_1 THEN statements_1 WHEN selector_value_2 THEN stat ...

  6. PL/SQL异常获取

    1.no_data SET SERVEROUTPUT ON DECLARE pename EMP.ENAME % TYPE ; BEGIN SELECT ename INTO pename FROM ...

  7. [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  8. Oracle PL/SQL中异常高级特性

    在OraclePL/SQL语句块中exception的异常处理部分是非常重要的组成部分,它决定了在PL/SQL语句块内部可执行部分在发生异常错误时,程序是友好地提示:程序遇到某些错误而无法执行,还是抛 ...

  9. PL\SQL结构控制、异常

    PL\SQL结构控制    1.IF条件控制语句(三种基本方式+IF语句的嵌套使用)        (1)IF...        (2)IF...ELSE        (3)IF...ELSIF. ...

随机推荐

  1. [libgdx游戏开发教程]使用Libgdx进行游戏开发(7)-屏幕布局的最佳实践

    管理多个屏幕 我们的菜单屏有2个按钮,一个play一个option.option里就是一些开关的设置,比如音乐音效等.这些设置将会保存到Preferences中. 多屏幕切换是游戏的基本机制,Libg ...

  2. 优化MySQL插入方法的五个妙招

    以下是涉及到插入表格的查询的5种改进方法: 1)使用LOAD DATA INFILE从文本下载数据这将比使用插入语句快20倍. 2)使用带有多个VALUES列表的INSERT语句一次插入几行这将比使用 ...

  3. (1)python Scrapy爬虫框架

    部署 1.安装python3.6  64bit 2.下载pywin32 https://sourceforge.net/projects/pywin32/files/pywin32/ 双击安装 3.下 ...

  4. 25、Django实战第25天:讲师详情页

    1.复制teacher-detail.html到templates目录下 2.编辑teacher-detail.html,继承base.html 3.编辑organization.view.py cl ...

  5. Windows 10 作为无线显示器无法被搜索到

    症状描述: Windows 10 的投影到此电脑功能失效,但是其它功能正常.同一网络,室友的电脑正常. 解决办法: 设备管理器启用“Microsoft Wi-Fi Direct Virtual Ada ...

  6. mysql 获取当前日期及格式化(转)

    MySQL 获取当前日期及日期格式 获取系统日期: NOW() 格式化日期: DATE_FORMAT(date, format) 注: date:时间字段,format:日期格式 select now ...

  7. 【dfs序】【树状数组】bzoj1103 [POI2007]大都市meg

    预处理出每个点到根节点的土路数,插到一个树状数组里,然后每次修改只会对子树中的节点造成影响,于是相当于区间修改.点查询了. #include<cstdio> using namespace ...

  8. 【前缀和】【前缀MAX】洛谷 P1351 NOIP2014提高组 day1 T2 联合权值

    不难发现,树中与某个点距离为2的点只可能是它的父亲的父亲.儿子的儿子 或者 兄弟,分类讨论一下即可. 只有对于兄弟我们不能暴力搞,维护一下每个节点的所有儿子的前缀和.前缀MAX就行了. #includ ...

  9. 【暴力】【推导】bzoj1088 [SCOI2005]扫雷Mine

    考虑右侧的一个格子是否放雷,只可能对其左侧的三个格子造成影响. 也就是说,若左侧一个格子旁的两个格子已经放了雷,对第三个格子也就唯一确定了. 因此只枚举前两个格子是否放雷,剩下的暴力判断是否合法即可. ...

  10. [CodeChef-DGTCNT]Chef and Digits

    题目大意: 若一个十进制数$x$(不含前导零)满足数码$i$恰好出现$t_i$次,则这个数是坏的,否则是好的.求区间$[L,R](1\le L,R\le10^{18})$中有多少好数. 思路: 显然可 ...