对于某些类型的错误,通常需要进行拦截并在过程或触发器内处理,而不是将其传递回调用环境。这是通过使用异常处理程序完成的。
使用复合语句的 EXCEPTION 部分来定义异常处理程序。请参见使用复合语句。
只要在复合语句中发生错误,异常处理程序就会执行。与错误不同,警告不会导致执行异常处理代码。如果错误出现在嵌套的复合语句中,或者出现在复合语句内任何地方所调用的过程或触发器中,异常处理代码也会执行。
中断错误 SQL_INTERRUPT、SQLSTATE 57014 的异常处理程序应只包含不可中断的语句,如 ROLLBACK 和 ROLLBACK TO SAVEPOINT 等。如果异常处理程序包含连接中断时调用的可中断语句,数据库服务器将在第一个可中断语句处停止异常处理程序,并返回中断错误。
用来说明异常处理情况的这一演示过程基于在过程和触发器中缺省的错误处理中所使用的过程。
在本例中,附加代码会在 InnerProc 过程中处理 [未找到列] 错误。
DROP PROCEDURE OuterProc; DROP PROCEDURE InnerProc; CREATE PROCEDURE OuterProc() BEGIN MESSAGE 'Hello from OuterProc.' TO CLIENT; CALL InnerProc(); MESSAGE 'SQLSTATE set to ', SQLSTATE,' in OuterProc.' TO CLIENT END; CREATE PROCEDURE InnerProc() BEGIN DECLARE column_not_found EXCEPTION FOR SQLSTATE '52003'; MESSAGE 'Hello from InnerProc.' TO CLIENT; SIGNAL column_not_found; MESSAGE 'Line following SIGNAL.' TO CLIENT; EXCEPTION WHEN column_not_found THEN MESSAGE 'Column not found handling.' TO CLIENT; WHEN OTHERS THEN RESIGNAL ; END; CALL OuterProc(); |
Interactive SQL [消息] 选项卡随后会显示以下内容:
Hello from OuterProc. Hello from InnerProc. Column not found handling. SQLSTATE set to 00000 in OuterProc. |
EXCEPTION 子句声明异常处理程序。EXCEPTION 后的各行直到错误发生时才会执行。每一 WHEN 子句都指定一个异常名称(用 DECLARE 语句声明)以及在遇到该异常时要执行的语句。WHEN OTHERS THEN 子句指定当所发生的异常没有出现在之前的 WHEN 子句时要执行的语句。
在此示例中,RESIGNAL 语句将该异常传递给更高级别的异常处理程序。如果在异常处理程序中不指定 WHEN OTHERS THEN,则 RESIGNAL 是缺省操作。
在 InnerProc 中,执行 EXCEPTION 处理程序,而不是执行 SIGNAL 语句之后的那些行。
因为遇到的错误是 [未找到列] 错误,因此执行其中用来处理该错误的 MESSAGE 语句,SQLSTATE 重置为零(指示没有发生任何错误)。
在异常处理代码执行后,控制被传递回 OuterProc,就像没有遇到任何错误一样继续执行。
不应将 ON EXCEPTION RESUME 与显式异常处理一起使用。如果包括 ON EXCEPTION RESUME,将不会执行异常处理代码。
如果 [未找到列] 异常的错误处理代码只是一个 RESIGNAL 语句,控制权会传递回 OuterProc 过程,SQLSTATE 仍然设置为值 52003。这就像是 InnerProc 中没有错误处理代码。由于在 OuterProc 中没有错误处理代码,因此该过程将失败。
在复合语句内处理异常时,复合语句结束时不会有活动的异常,出现异常前所做的更改也不被回退。即使对于原子复合语句,上述情况也同样适用。如果错误在原子复合语句内发生并被显式处理,则该原子复合语句中的某些语句(而非全部语句)会执行。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |