Oracle异常 创建并抛出命名的自定义异常
2016-12-18 10:53
399 查看
9.3 创建并抛出命名的自定义异常
问题
你想在某个特定事件发生时向应用程序的用户发出一些警告信息。事件本身不会抛出Oracle内部异常,因为这个异常是属于应用程序的特定异常。所以,你需要把这个事件与自定义异常关联起来,这样一来,不论事件在什么时候发生异常都可以抛出。解决方案
声明一个用户定义的命名异常,并把它与你想抛出的异常事件相关联。下面的例子在代码块中声明并抛出一个用户定义的异常。异常抛出时,应用程序的控制权就会传递给控制用户命名异常的异常处理程序。CREATE OR REPLACE PROCEDURE salary_increase(emp_id IN NUMBER, pct_increase IN NUMBER) AS salary employees.salary%TYPE; max_salary jobs.max_salary%TYPE; INVALID_INCREASE EXCEPTION; BEGIN SELECT salary, max_salary INTO salary, max_salary FROM employees, jobs WHERE employee_id = emp_id AND jobs.job_id = employees.employee_id; IF (salary + (salary * pct_increase)) <= max_salary THEN UPDATE employees SET salary = (salary + (salary * pct_increase)) WHERE employee_id = emp_id; DBMS_OUTPUT.PUT_LINE('SUCCESSFUL SALARY INCREASE FOR EMPLOYEE #: ' || emp_id || '. NEW SALARY = ' || salary + (salary * pct_increase)); ELSE RAISE INVALID_INCREASE; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('UNSUCCESSFUL INCREASE, NO EMPLOYEE RECORD FOUND ' || 'FOR THE GIVEN ID'); WHEN INVALID_INCREASE THEN DBMS_OUTPUT.PUT_LINE('UNSUCCESSFUL INCREASE. YOU CANNOT INCREASE THE ' || 'EMPLOYEE SALARY BY ' || pct_increase || 'PERCENT...PLEASE ENTER ' || 'A SMALLER INCREASE AMOUNT TO TRY AGAIN'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('UNSUCCESSFUL INCREASE. AN UNCKNOWN ERROR HAS '|| 'OCCURRED, ' || 'PLEASE TRY AGAIN OR CONTACT ADMINISTRATOR' || pct_increase); END; /
从代码中可以看出,异常块可以容纳一个或多个处理程序。命名的用户异常在过程的声明部分声明,并且这个异常可以在代码块的任何地方抛出。
注意 在真实的应用程序中,异常应该在OTHERS处理程序中手动引发。关于如何确定异常起因的更多内容请参考9.4节。
原理分析
一个PL/SQL应用程序可以包含任意数量的自定义异常。开发人员声明了他们自己的异常时,这些异常就称为用户定义异常。用户定义异常必须在包、函数、过程或匿名代码块的声明部分声明。要声明一个异常,可以使用下面的语法:exception_name EXCEPTION;
对于异常的命名,只要符合标准的命名规范并且不同于内部定义的异常名称,都可以使用。规范的异常名称应该全部采用大写,但小写也可以使用,因为PL/SQL语言不区分大小写。
如果想抛出你自己的异常,需要在RAISE关键字后面加上你要抛出的异常名称。代码执行到RAISE语句时,控制权就会传递给与命名异常最为匹配的异常处理程序。如果找不到与抛出异常相匹配的异常处理程序,控制权就会传入OTHERS处理程序,但前提是存在OTHERS处理程序。而在最糟糕的情况下,如果没有任何异常处理程序能够与RAISE语句中抛出的异常名称相匹配,并且代码中也没有编写OTHERS处理程序,控制权就会被传回外层代码块、调用当前程序的代码块或是宿主环境。
关于RAISE语句,除了上面提到的一种用法之外,还有别的用法。比如抛出一个在其他包中声明的异常。为此,需要在异常的前面加上完整的包名作为前缀。另外,RAISE语句也可以独立使用,用来重新抛出一个异常。
从这个案例的解决方案中可以看出,捕获命名的用户异常与捕获内部定义异常完全一样。都是编写一个WHEN…THEN子句,中间放你想捕获的异常名字。异常抛出时,会执行对应异常处理程序中包含的语句。
相关文章推荐
- ORACLE中 抛出异常1
- Oracle自定义异常的使用 推荐
- oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标,异常处理,自定义异常,
- C# catch 块中可以俘获 SQL Server 抛出的自定义异常(RAISERROR)(轉)
- oracle异常(预定义异常,自定义异常)
- 错误处理: 从托管的 COM+ 服务器应用中抛出自定义异常类型
- oracle 异常处理、异常分类、异常的抛出、异常的传播
- 自定义异常和抛出异常 推荐
- oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标,异常处理,自定义异常,
- 自定义异常的声明和抛出
- SQL Server 自定义异常及抛出自定义异常
- [原创]Enterprise Library深入解析与灵活应用(4):创建一个自定义Exception Handler改变ELAB的异常处理机制
- oracle共享服务器创建成功后,通过jdbc连接数被限制,报错:java.sql.SQLException: Io 异常: End of TNS data channel解决方法
- Oracle中自定义异常处理
- Oracle 已命名的异常
- oracle数据异常处理--抛出特定异常(转)
- C# catch 块中可以俘获 SQL Server 抛出的自定义异常(RAISERROR)(轉)
- oracle 在存储过程自定义异常的处理方法
- oracle10g- oracle关于数据操作时异常的处理 编写自定义的异常
- oracle 隐式游标,显示游标,游标循环,动态SELECT语句和动态游标,异常处理,自定义异常,