ORACLE EXCEPTION小结
ORACLE EXCEPTION总结
ORACLE EXCEPTION总结
2011年09月01日
一 ORACLE EXCEPTION只包含三种异常:
1.System Error,例如:Out of memory---由Oracle定义并由PL/SQL Runtime引擎在检测到错误所 产生的异常,包含在STANDARD PACKAGE中。
2.用户行为导致的Error(重点介绍)
3.应用程序给出的Warning.
二 捕获异常的机制:
用一种异常句柄来捕捉和响应错误。异常句柄提供了一种类似事件驱动的模式,也就是说,不管在何时何地发生错误,都能被同一代码捕获到。
无论在系统或程序中,一旦出现错误时,可执行程序被中断,都会将控制权交与异常处理代码,异常处理代码处理完成后,控制权会回到外围模块的代码中。例如;
BEGIN INSERT INTO A VALUES A_ROWTYPE; V_SUCC_FLG := '1'; EXCEPTION WHEN OTHERS THEN V_SQL_ERR_MSG := SQLERR; END;
如果在insert出现Exception时,第三行将不再之行,而是直接进入到第五行,执行完后,会回到调用此Procedure的外围方法上。
三 用户定义的异常:
1.自定义异常:
当我们在实际应用中总会碰到一些异常是无法在系统中预先被定义的,需要手动去捕获,同时抛出来,告诉使用系统的终端用户具体的错误信息。在PL/SQL中,用Raise手动产生。例如:
PROCEDURE P_CALCU_POL_PREM(I_POL_ID IN VARCHAR2)AS INVALID_POLICY_NO EXCEPTION; INVALID_PRODUCT_NO EXCEPTION; BEGIN BEGIN SELECT CM.POL_NO INTO V_POL_NO FROM T_CONTR_MST CM WHERE CM.POL_ID := I_POL_ID; SELECT CP.PRD_NO INTO V_PRD_NO FROM T_CONTR_PRD CP WHERE CP.POL_ID := I_POL_ID; EXCEPTION WHEN INVALID_POLICY_NO THEN RAISE; WHEN INVALID_PRODUCT_NO THEN RAISE; END; END P_CALCU_POL_PREM;
2 为非定义异常关联一个名字:
一般可以用RAISE_APPLICATION_ERROR来定义一个包含ERROR_CODE和描述的异常。
首先,需要用到PRAGMA EXCEPTION_INIT(EXCEPTION, INTEGER),这样就把非预定义异常 同Error_Code相关联起来了。Notes:ERROR_Code只能从-20000~-20999中取值,并且因为EXCEPTION_INIT是编译时运行的函数,所以必须放在PACKAGE里的声明部分。例如:
INVALID_POLICY_NO EXCEPTION;
PRAGMA EXCEPTION_INIT(INVALID_POLICY_NO, -20011);
四 自定义异常的触发:
对于自定义的异常,SQLCODE = 1.通常抛出异常,都通过RAISE.而Raise有以下三种形式:
◎ RAISE EXCEPTION
◎ RAISE PACKAGE.EXCEPTION
◎ RAISE
PL/SQL使用RAISE_APPLICATION_ERROR过程来生成一个具体描述的异常。例如:
PROCEDURE P_CALCU_POL_PREM(I_POL_ID IN VARCHAR2)AS INVALID_POLICY_NO EXCEPTION; INVALID_PRODUCT_NO EXCEPTION; BEGIN BEGIN SELECT CM.POL_NO INTO V_POL_NO FROM T_CONTR_MST CM WHERE CM.POL_ID := I_POL_ID; SELECT CP.PRD_NO INTO V_PRD_NO FROM T_CONTR_PRD CP WHERE CP.POL_ID := I_POL_ID; EXCEPTION WHEN INVALID_POLICY_NO THEN RAISE_APPLICATION_ERROR(ERROR_CODE,ERROR_MSG) ; WHEN INVALID_PRODUCT_NO THEN RAISE ....; END; END P_CALCU_POL_PREM;
在Handle Exception的时候,一般会做数据回滚(ROLLBACK),这里涉及到SAVEPOINT的问题,会对在同一事务里所有的DML操作进行还原。
五 异常的确定和分析:
PL/SQL提供了一些内置的函数进行分析处理。
1.SQLCODE:
当没有异常产生时候,SQLCODE=0,反之为1.
2 SQLERRM:
SQLERRM---接受返回值,通常长度不超过512B.如果超过时,需要使用DBMS_UTILITY.FORMAT_ERROR_STACK.但在实际应用中,一般都会对其进行重新包装的。
3.DBMS_UTILITY.FORMAT_ERROR_STACK。
举个实例:
UNKNOWN_ERR_CODE EXCEPTION; PRAGMA EXCEPTION_INIT(UNKNOWN_ERR_CODE, -20099); PROCEDURE P_HANDLE_EXCEPTION(I_ERR_CODE IN NUMBER)AS BEGIN SELECT SR.MSG_DES INTO V_MSG_DES FROM T_STRING_RESOURCE SR WHERE SR.MSG_ID = I_ERR_CODE; IF V_MSG_DES IS NOT NULL THEN IF (I_ERR_CODE = 20091) THEN RAISE_APPLICATION_ERROR(I_ERR_CODE,V_MSG_DES); ELSIF (I_ERR_CODE = 20092) THEN RAISE_APPLICATION_ERROR(I_ERROR_CODE,V_MSG_DES||'I _ERR_CODE') END IF; ELSE RAISE_APPLICATION_ERROR(UNKNOWN_ERR_CODE); END IF; END P_HANDLE_EXCEPTION; PROCEDURE P_CALCU_PRD_PREM(I_POL_ID IN VARCHAR2)AS V_PROD_PREM NUMBER(10,2); V_PRD_INSURE_NUM NUMBER; BEGIN BEGIN SELECT CP.PRD_PREM,CP.PRD_INSURE_NUM INTO V_PROD_PREM,V_PRD_INSURE_NUM FROM T_CONTR_PROD CP WHERE CP.POL_ID = I_POL_ID; V_PRD_AVG_PREM := V_PROD_PREM / V_PRD_INSURE_NUM; EXCEPTION P_HANDLE_EXCEPTION(SQLERRM); END; END P_CALCU_PRD_PREM;
ORACLE EXCEPTION总结
2011年09月01日
一 ORACLE EXCEPTION只包含三种异常:
1.System Error,例如:Out of memory---由Oracle定义并由PL/SQL Runtime引擎在检测到错误所 产生的异常,包含在STANDARD PACKAGE中。
2.用户行为导致的Error(重点介绍)
3.应用程序给出的Warning.
二 捕获异常的机制:
用一种异常句柄来捕捉和响应错误。异常句柄提供了一种类似事件驱动的模式,也就是说,不管在何时何地发生错误,都能被同一代码捕获到。
无论在系统或程序中,一旦出现错误时,可执行程序被中断,都会将控制权交与异常处理代码,异常处理代码处理完成后,控制权会回到外围模块的代码中。例如;
BEGIN INSERT INTO A VALUES A_ROWTYPE; V_SUCC_FLG := '1'; EXCEPTION WHEN OTHERS THEN V_SQL_ERR_MSG := SQLERR; END;
如果在insert出现Exception时,第三行将不再之行,而是直接进入到第五行,执行完后,会回到调用此Procedure的外围方法上。
三 用户定义的异常:
1.自定义异常:
当我们在实际应用中总会碰到一些异常是无法在系统中预先被定义的,需要手动去捕获,同时抛出来,告诉使用系统的终端用户具体的错误信息。在PL/SQL中,用Raise手动产生。例如:
PROCEDURE P_CALCU_POL_PREM(I_POL_ID IN VARCHAR2)AS INVALID_POLICY_NO EXCEPTION; INVALID_PRODUCT_NO EXCEPTION; BEGIN BEGIN SELECT CM.POL_NO INTO V_POL_NO FROM T_CONTR_MST CM WHERE CM.POL_ID := I_POL_ID; SELECT CP.PRD_NO INTO V_PRD_NO FROM T_CONTR_PRD CP WHERE CP.POL_ID := I_POL_ID; EXCEPTION WHEN INVALID_POLICY_NO THEN RAISE; WHEN INVALID_PRODUCT_NO THEN RAISE; END; END P_CALCU_POL_PREM;
2 为非定义异常关联一个名字:
一般可以用RAISE_APPLICATION_ERROR来定义一个包含ERROR_CODE和描述的异常。
首先,需要用到PRAGMA EXCEPTION_INIT(EXCEPTION, INTEGER),这样就把非预定义异常 同Error_Code相关联起来了。Notes:ERROR_Code只能从-20000~-20999中取值,并且因为EXCEPTION_INIT是编译时运行的函数,所以必须放在PACKAGE里的声明部分。例如:
INVALID_POLICY_NO EXCEPTION;
PRAGMA EXCEPTION_INIT(INVALID_POLICY_NO, -20011);
四 自定义异常的触发:
对于自定义的异常,SQLCODE = 1.通常抛出异常,都通过RAISE.而Raise有以下三种形式:
◎ RAISE EXCEPTION
◎ RAISE PACKAGE.EXCEPTION
◎ RAISE
PL/SQL使用RAISE_APPLICATION_ERROR过程来生成一个具体描述的异常。例如:
PROCEDURE P_CALCU_POL_PREM(I_POL_ID IN VARCHAR2)AS INVALID_POLICY_NO EXCEPTION; INVALID_PRODUCT_NO EXCEPTION; BEGIN BEGIN SELECT CM.POL_NO INTO V_POL_NO FROM T_CONTR_MST CM WHERE CM.POL_ID := I_POL_ID; SELECT CP.PRD_NO INTO V_PRD_NO FROM T_CONTR_PRD CP WHERE CP.POL_ID := I_POL_ID; EXCEPTION WHEN INVALID_POLICY_NO THEN RAISE_APPLICATION_ERROR(ERROR_CODE,ERROR_MSG) ; WHEN INVALID_PRODUCT_NO THEN RAISE ....; END; END P_CALCU_POL_PREM;
在Handle Exception的时候,一般会做数据回滚(ROLLBACK),这里涉及到SAVEPOINT的问题,会对在同一事务里所有的DML操作进行还原。
五 异常的确定和分析:
PL/SQL提供了一些内置的函数进行分析处理。
1.SQLCODE:
当没有异常产生时候,SQLCODE=0,反之为1.
2 SQLERRM:
SQLERRM---接受返回值,通常长度不超过512B.如果超过时,需要使用DBMS_UTILITY.FORMAT_ERROR_STACK.但在实际应用中,一般都会对其进行重新包装的。
3.DBMS_UTILITY.FORMAT_ERROR_STACK。
举个实例:
UNKNOWN_ERR_CODE EXCEPTION; PRAGMA EXCEPTION_INIT(UNKNOWN_ERR_CODE, -20099); PROCEDURE P_HANDLE_EXCEPTION(I_ERR_CODE IN NUMBER)AS BEGIN SELECT SR.MSG_DES INTO V_MSG_DES FROM T_STRING_RESOURCE SR WHERE SR.MSG_ID = I_ERR_CODE; IF V_MSG_DES IS NOT NULL THEN IF (I_ERR_CODE = 20091) THEN RAISE_APPLICATION_ERROR(I_ERR_CODE,V_MSG_DES); ELSIF (I_ERR_CODE = 20092) THEN RAISE_APPLICATION_ERROR(I_ERROR_CODE,V_MSG_DES||'I _ERR_CODE') END IF; ELSE RAISE_APPLICATION_ERROR(UNKNOWN_ERR_CODE); END IF; END P_HANDLE_EXCEPTION; PROCEDURE P_CALCU_PRD_PREM(I_POL_ID IN VARCHAR2)AS V_PROD_PREM NUMBER(10,2); V_PRD_INSURE_NUM NUMBER; BEGIN BEGIN SELECT CP.PRD_PREM,CP.PRD_INSURE_NUM INTO V_PROD_PREM,V_PRD_INSURE_NUM FROM T_CONTR_PROD CP WHERE CP.POL_ID = I_POL_ID; V_PRD_AVG_PREM := V_PROD_PREM / V_PRD_INSURE_NUM; EXCEPTION P_HANDLE_EXCEPTION(SQLERRM); END; END P_CALCU_PRD_PREM;