oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)
什么是异常?
在PL/SQL中的一个标识。
在程序运行期间被触发的错误。
异常是怎样被触发的?
产生一个Oracle错误。
用户显示触发。
怎样处理异常?
用异常处理句柄捕获异常。
传播异常到调用环境。

捕获异常
EXCEPTION
WHEN exception1 [OR exception2 . . .] THEN
statement1;
statement2;
. . .
[WHEN exception3 [OR exception4 . . .] THEN
statement1;
statement2;
. . .]
[WHEN OTHERS THEN
statement1;
statement2;
. . .]
异常捕获规则
WHEN OTHERS用于捕获所有未指定错误。必须是最后一个错误处理语句。
EXCEPTION关键字,标识异常处理的开始区域。
允许有多个异常处理子句。
在离开异常处理程序块之前,只能有一个错误处理子句被执行。
捕获Oracle服务器预定义错误
CASE_NOT_FOUND (ORA-06592)
NO_DATA_FOUND (ORA-1403)
TOO_MANY_ROWS (ORA-1422)
DUP_VAL_ON_INDEX (ORA-0001)
ZERO_DIVIDE (ORA-1476)
INVALID_CURSOR (ORA-1001)
VALUE_ERROR (ORA-6502)
语法:
BEGIN SELECT ... COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
statement1;
statement2;
WHEN TOO_MANY_ROWS THEN
statement1;
WHEN OTHERS THEN
statement1;
statement2;
statement3;
END;
实例
DECLARE
v_empRecord emp%ROWTYPE;
v_empNo emp.empno%TYPE;
BEGIN
SELECT * INTO v_empRecord FROM emp;
--SELECT * INTO v_empRecord FROM emp WHERE empno = 12345;
--SELECT ename INTO v_empNo FROM emp WHERE empno = 7369;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('TOO_MANY_ROWS EXCEPTION');
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('NO_DATA_FOUND EXCEPTION');
WHEN OTHERS THEN
dbms_output.put_line('OTHERS EXCEPTION');
END;
捕获Oracle服务器错误
将数字-2292与e_products_invalid相关联。(-2292表示违反了完整性约束)
DECLARE
e_products_invalid EXCEPTION;
PRAGMA EXCEPTION_INIT (
e_products_invalid, -2292);
v_message VARCHAR2(50);
BEGIN
. . .
EXCEPTION
WHEN e_products_invalid THEN
:g_message := 'Product code
specified is not valid.';
. . .
END;
example
为emp表创建一个能完成插入功能的存储过程insert_emp。
CREATE OR REPLACE PROCEDURE insert_emp
(no IN emp.empno%TYPE, name IN emp.ename%TYPE DEFAULT NULL,
job IN emp.job%TYPE DEFAULT 'SALESMAN',
mgr IN emp.mgr%TYPE DEFAULT 7369,
hiredate emp.hiredate%TYPE DEFAULT SYSDATE,
salary emp.sal%TYPE DEFAULT 800,
comm emp.comm%TYPE DEFAULT NULL,
deptno emp.deptno%TYPE DEFAULT 10
)IS
e_integrity EXCEPTION;
PRAGMA EXCEPTION_INIT (e_integrity,-2291);
BEGIN
INSERT INTO emp VALUES(no,name,job,mgr,hiredate,salary,comm,deptno);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dbms_output.put_line('该员工已经存在!');
WHEN e_integrity THEN
dbms_output.put_line('部门编号填写错误!');
END;

example 向emp表中插入一条新记录,在执行的过程中捕获系统预定义异常、系统非预定义异常、用户自定义异常,并分别作相应的处理。
DECLARE
ex_null EXCEPTION; --系统非预定义异常的定义和关联
PRAGMA EXCEPTION_INIT(ex_null,-01400);
ex_insert EXCEPTION; --用户自定义异常的定义
eno scott.emp.empno%TYPE:=&no; --定义程序块变量
e_sal scott.emp.sal%TYPE:=&salary;
BEGIN
IF e_sal>10000 THEN
RAISE ex_insert; --用户自定义异常的触发
ELSE
INSERT INTO scott.emp(empno,sal) VALUES(eno,e_sal);
END IF;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN --系统预定义异常的捕获和处理
dbms_output.put_line('该员工已经存在!');
WHEN ex_null THEN --系统非预定义异常的捕获和处理
dbms_output.put_line('职工编号不能为空!');
WHEN ex_insert THEN --用户自定义异常的捕获和处理
dbms_output.put_line('员工的工资不能超过10000!');
END;
捕获异常中的函数
SQLCODE
返回错误代码。
SQLERRM
返回与错误代码相关联的消息。
DECLARE
v_error_code NUMBER;
v_error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
ROLLBACK;
v_error_code := SQLCODE ;
v_error_message := SQLERRM ;
INSERT INTO errors VALUES(v_error_code,
v_error_message);
END;
RAISE_APPLICATION_ERROR
raise_application_error (error_number,
message[, {TRUE | FALSE}]);
从存储过程中触发用户自定义异常。
...
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR (-20201,'Manager is not a valid employee.');
END;
例8.4 为scott.emp表创建一个能完成插入功能的存储过程insert_emp。
CREATE OR REPLACE PROCEDURE insert_emp
(no IN scott.emp.empno%TYPE,
name IN scott.emp.ename%TYPE DEFAULT NULL,
job IN scott.emp.job%TYPE DEFAULT 'SALESMAN',
mgr IN scott.emp.mgr%TYPE DEFAULT 7369,
hiredate scott.emp.hiredate%TYPE DEFAULT SYSDATE,
salary scott.emp.sal%TYPE DEFAULT 800,
comm scott.emp.comm%TYPE DEFAULT NULL,
deptno scott.emp.deptno%TYPE DEFAULT 10
)
IS
e_integrity EXCEPTION;
PRAGMA EXCEPTION_INIT (e_integrity,-2291);
BEGIN
INSERT INTO scott.emp VALUES(no,name,job,mgr,hiredate,salary,comm,deptno);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dbms_output.put_line('该员工已经存在!');
WHEN e_integrity THEN
dbms_output.put_line('部门编号填写错误!');
END;
oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)的更多相关文章
- oracle PL/SQL(procedure language/SQL)程序设计
PL/SQL(procedure language/SQL)语言是Oracle对SQL语言的过程化扩充,是一个完整的编程语言.PL/SQL实现了过程化语句(如分支.循环等)与SQL语句的无缝连接,将过 ...
- Oracle笔记--PL/SQL(Procedure Language & Structured Query Language)
1.PL/SQL是一种高级数据库程序设计语言,专门用于在各种环境下对Oracle数据库进行访问.该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理. 2.PL/SQL是对SQ ...
- oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包
匿名PL/SQL块回顾 DECLARE (可选) 定义在PL/SQL块中要使用的对象BEGIN (必须) 执行语句EXCEPTION (可选) 错误处理语句END; (必须)匿名块( ...
- oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包(转)
匿名PL/SQL块回顾 DECLARE (可选) 定义在PL/SQL块中要使用的对象 BEGIN (必须) 执行语句 EXCEPTION (可选) 错误处理语句 END; (必 ...
- oracle PL/SQL(procedure language/SQL)程序设计之游标cursors
游标 Cursors--Conception 每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SE ...
- oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)
创建触发器 触发器类似于过程和函数,都拥有声明.执行和异常处理过程的带名PL/SQL块.与包类似,触发器必须存储在数据库中.前面已经讲过,过程是显式地通过过程调用执行的,同时过程调用可以传递参数.与之 ...
- oracle PL/SQL(procedure language/SQL)程序设计(在PL/SQL中使用SQL)
在PL/SQL程序中,允许使用的SQL语句只有DML和事务控制语句,使用DDL语句是非法的.使用SELECT语句从数据库中选取数据时,只能返回一行数据.使用COMMIT, ROLLBACK, 和SA ...
- oracle PL/SQL(procedure language/SQL)程序设计--控制结构(if else )
IF逻辑结构:IF-THEN-END IFIF-THEN-ELSE-END IFIF-THEN-ELSIF-END IF 语法 IF condition THEN statements;[ELSIF ...
- oracle PL/SQL(procedure language/SQL)程序设计(续集)之PL/SQL函数
PL/SQL函数 examples:“ 构造一个邮件地址 v_mailing_address := v_name||CHR(10)|| ...
随机推荐
- thinkPHP 无法create,无法插入数据,提示非法数据对象
4.thinkPHP 无法create,提示非法数据对象解决方法:不要create+add,而用 data[]= '';+add$m_r_fa_account = D('R_fa_account'); ...
- Find mac address
Windows Method 1: Using the Command Prompt 1 Click on the Start button. 2 Type cmd in the search b ...
- Spring优势
* 使用spring有什么好处? ◆Spring能有效地组织你的中间层对象,无论你是否选择使用了EJB.如果你仅仅使用了Struts或其他的包含了J2EE特有APIs的framework,你会发现S ...
- ASP.NET基础之HttpModule 、HttpContext、 HttpHandler
http://www.cnblogs.com/wujy/p/3261141.html http://www.cnblogs.com/wujy/p/3264475.html http://www.cnb ...
- 在XAF(ASP.NET)中以ListEditor的形式调用百度地图API
因为项目需要,在系统中使用地图显示设备的地理位置.考虑过ArgGIS,Bing和Baidu地图.本来想用ArgGIS,看教程嫌麻烦.所以还是用Web地图吧.Bing的话还要申请个key,没心情.百度地 ...
- 本地存储(cookie&sessionStorage&localStorage)
好文章,最全面.就查它吧:https://segmentfault.com/a/1190000004556040 1.DOM存储:https://developer.mozilla.org/zh-CN ...
- Javascript模块规范(CommonJS规范&&AMD规范)
Javascript模块化编程(AMD&CommonJS) 前端模块化开发的价值:https://github.com/seajs/seajs/issues/547 模块的写法 查看 AMD规 ...
- C#与excel互操作的错误无法将类型为“Excel.ApplicationClass”的COM 对象强制转换为接口类型“Excel._Application”
如果您使用的电脑要操作的是office2003而之前使用过office2007使用此方法可解决您的问题 无法将类型为“Microsoft.Office.Interop.Excel.Applicatio ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- 关于android 图像格式问题
这算是篇总结吧.6月份开始做的一个android上的ar项目结束了.我做的部分是二维码识别和图像识别的预处理.这个项目虽然很累,但是让我学到了很多东西,特别是严格的编码规则,和java代码的效率优化, ...