日期:2014-05-16  浏览次数:20524 次

嵌入SQL中(DB2)异常处理WHENEVER语句的使用

WHENEVER语句用于异常处理,这里的异常包括:ERROR、EXCEPTION、WARNING。

这个异常的处理,主要是检查SQLSTATE和SQLCODE这两个保存SQL运行状态的值。

语法格式为:

EXEC SQL
    WHENEVER condition action
END-EXEC

WHENEVER语句的作用域:

一个程序中可以出现多个WHENEVER语句,若程序中只有一个WHENEVER语句,

其作用域为从其出现的地方到程序结束;若有多个异常处理语句,上一个语句的作用域为,

从其定义到遇到下一个异常处理语句为止。


能够处理的情况(condition)分三种:

SQLWARNING:在处理数据的过程中,如数据被截取,或数字四舍五入之类的,将会出现警告,

     此时:SQLCODE>0 and SQLCODE!=100,SQLWARN0=W,SUBSTR(SQLSTATE,1,2)='01'

SQLERROR:当SQL语句写的不正确或者其他异常情况发生的时候,

     DB2就会在出现错误的地方给SQLCODE,SQLSTATE赋值:SQLCODE<0,SUBSTR(SQLSTATE,1,2)>'02'

NOT FOUND:常见于从游标中读取数据,为了处理读取到最后一条数据之后的处理;

     也可以用在UPDATE,DELETE,INSERT语句之后判断,这种情况下表示没有数据受到影响。

     此时:SQLCODE=100,SQLSTATE='02000'。


对于上面的这三种异常,可以采取的行动(action)为:

CONTINUE:继续处理接下来的程序代码,忽略此异常。

GOTO label:对异常进行处理,label类似于JAVA中定义的catch部分,进行异常处理。

     如在RPGLE程序中嵌入SQL,游标处理当中,可以对NOT FOUND异常进行处理:

     WHENEVER NOT FOUND GOTO CLOS1,在CLOS1部分关闭此游标。

eg:

 *异常处理
C/EXEC SQL WHENEVER NOT FOUND GOTO CLOS1
C/END-EXEC
...
 *处理游标
C/EXEC SQL DECLARE C1 CURSOR FOR SELECT ...
C/END-EXEC
...
 *异常处理:关闭游标
C     CLOS1         TAG
C/EXEC SQL CLOSE C1
C/END-EXEC
...
关于SQLCODE和SQLSTATE的值:
没执行一条SQL语句,DB2都会给他们赋值,正确反应当前SQL执行的状态,失败了?成功了?警告了?
所以我们在没执行一条SQL之后,最好通过检查其SQLCODE和SQLSTATE来确认其是否符合业务逻辑。

--the end--