资源描述
单击此处编辑母版标题样式,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,Oracle SQL&PL/SQL,第,21,章,异常,本章要点,定义,PL/SQL,异常,列出并使用不同类型的,PL/SQL,异常处理器语句,截获无法预料的错误,描述嵌套块中异常传播的影响,自定义,PL/SQL,异常消息命令,处理,PL/SQL,异常,什么是异常,?,在,PL/SQL,中的一个警告或错误都是异常。,异常是如何触发的,?,发生了一个,Oracle,错误时。,使用,RAISE,语句显式触发。,如何处理异常,?,用处理机截获。,在调用环境中传播异常。,异常处理,截获异常,DECLARE,BEGIN,END;,触发异常,EXCEPTION,截获异常,异常的传播,DECLARE,BEGIN,END;,触发异常,EXCEPTION,异常没有被截获,异常传播给了调用环境,异常的类型,Oracle,服务器的预定义异常,Oracle,服务器没有预定义的异常,自定义异常,隐式触发,显式触发,截获异常,EXCEPTION,WHEN exception1 OR exception2.THEN,statement1;,statement2;,.,WHEN exception3 OR exception4.THEN,statement1;,statement2;,.,WHEN OTHERS THEN,statement1;,statement2;,.,语法:,截获异常的原则,WHEN OTHERS,是最后一个子句。,异常处理部分从关键字,EXCEPTION,开始。,允许有多个异常处理机。,在离开块之前只能执行一个处理机。,在赋值语句和,SQL,语句中不能使用异常,截获,Oracle,服务器预定义的错误,在相应的异常处理例程中引用错误的标准名。,一些预定义异常:,NO_DATA_FOUND,TOO_MANY_ROWS,INVALID_CURSOR,ZERO_DIVIDE,DUP_VAL_ON_INDEX,预定义异常,BEGIN,EXCEPTION,WHEN NO_DATA_FOUND THEN,statement1;,statement2,;,WHEN TOO_MANY_ROWS THEN,statement1,;,WHEN OTHERS THEN,statement1;,statement2;,statement3,;,END;,语法:,截获,Oracle,服务器没有预定义的错误,Declare,命名异常,Associate,编译指令,PRAGMA,EXCEPTION_INIT,声明部分,Reference,处理被触发的异常,异常处理部分,DECLARE,e_,emps,_remainingEXCEPTION;,PRAGMA EXCEPTION_INIT(,e_,emps,_remaining,-2292);,v_,deptno,dept.,deptno,%TYPE:=&p_,deptno,;,BEGIN,DELETE FROM dept,WHERE,deptno,=v_,deptno,;,COMMIT;,EXCEPTION,WHEN e_,emps,_remaining THEN,DBMS_OUTPUT.PUT_LINE(Cannot remove dept|,TO_CHAR(v_,deptno,)|.Employees exist.);,END;,没有预定义的错误,截获,Oracle,代码为,2292,的违反完整性约束的错误。,e_,emps,_remaining EXCEPTION;,1,PRAGMA EXCEPTION_INIT(,e_,emps,_remaining,-2292);,2,e_,emps,_remaining,3,截获异常的函数,SQLCODE,返回,Oracle,的错误代码,SQLERRM,返回,Oracle,的错误消息,不能在,SQL,语句中直接使用这两个函数,而必须将这些值赋给,SQL,语句中的局部变量。,截获异常的函数,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;,举例:,SQLCODE,SQLERRM,截获自定义的异常,命名异常,Declare,声明部分,Raise,使用,RAISE,语句显式发布异常,执行部分,Reference,处理出现的异常,异常处理部分,自定义异常,DECLARE,e_invalid_product EXCEPTION;,BEGIN,UPDATEproduct,SET,descrip,=&product_description,WHERE,prodid,=,IF SQL%NOTFOUND THEN,RAISE e_invalid_product;,END IF;,COMMIT;,EXCEPTION,WHEN e_invalid_product THEN,DBMS_OUTPUT.PUT_LINE(Invalid product number.);,END;,举例:,e_invalid_product EXCEPTION;,1,RAISE e_invalid_product;,2,e_invalid_product,3,调用环境,SQL*Plus,Procedure Builder,OracleDeveloperForms,Precompiler,application,An enclosing PL/SQL block,在屏幕上显示错误代码和错误消息,在屏幕上显示错误代码和错误消息,使用,ERROR_CODE,和,ERROR_TEXT,包函数访问错误代码和错误消息,通过,SQLCA,数据结构访问异常代码,在外部块的异常处理例程中截获异常,异常的传播,BEGIN,SELECT.,UPDATE.,IF SQL%NOTFOUND THEN,RAISE e_no_rows;,END IF;,EXCEPTION,WHEN e_integrity THEN.,WHEN e_no_rows THEN.,END;,DECLARE,.,e_no_rowsexception;,e_integrityexception;,PRAGMA EXCEPTION_INIT(e_integrity,-2292);,BEGIN,FOR c_record IN,emp,_cursor LOOP,END LOOP;,EXCEPTION,WHEN NO_DATA_FOUND THEN.,WHEN TOO_MANY_ROWS THEN.,END;,子块可以自己处理异常也可以将异常传递给外部块,BEGIN,SELECT.,UPDATE.,IF SQL%NOTFOUND THEN,RAISE e_no_rows;,END IF;,EXCEPTION,WHEN e_integrity THEN.,WHEN e_no_rows THEN.,END;,RAISE_APPLICATION_ERROR,语法:,这个过程允许在存储子程序中发布用户自定义的错误消息。,只能从一个正在执行的存储子程序中调用该过程。,raise_application_error(,error_number,message,TRUE|FALSE);,RAISE_APPLICATION_ERROR,在两个不同的地方使用,:,执行部分,异常处理部分,向用户返回错误,并且其返回格式和其它,Oracle,错误的格式相同。,小结,异常的类型,:,Oracle,服务器的预定义异常,Oracle,服务器没有预定义的异常,自定义异常,异常的截获,异常处理,:,截获,PL/SQL,块中的异常。,传播异常。,
展开阅读全文