[GBase 8s 教程]GBase 8s 存储过程中的异常处理
异常捕获:ON EXCEPTION
用ON EXCEPTION 语句捕获一个或一组特定的异常(即错误),用错误号 标识。
ON EXCEPTION 语句与RAISE EXCEPTION 语句一起 提供存储过程语言(SPL)的错误 捕获和恢复机制。
在一个语句块内可以定义多个 ON EXCEPTION 语句。
被捕获的异常可以是系统异常或用户定义的异常。
一旦异常被捕获, 错误状态即被清除。
ON EXCEPTION 语句的位置:
ON EXCEPTION 语句是一声明性而非执行性语句, 故应位于任何执行语句之前,而位于DEFINE 语句之后。
格式
ON EXCEPTION IN (错误号, ...)
SET SQL错误变量, ISAM错误变量,错误文本变量
语句块
END EXCEPTION [WITH RESUME]
IN 子句说明欲捕获的错误号, 缺省时捕获所有的错误号。
SET 子句接收错误号和错误文本的变量,该语句可省略。
SQL 错误变量:说明接收SQL 错误号的变量
ISAM错误变量:说明接收ISAM错误号的变量
错误文本变量:说明接收与SQL错误号对应的错误文本的变量
WITH RESUME 关键字用于把控制转向到捕获的错误被处理后的紧接发生 异常语句后的语句,其效果相当于异常被处理后程序继续 执行下去。 WITH RESUME 可以省略。
示例:
下例捕获多个错误, 并采取相应措施。若错误号 为300采取措施B, 若错误号为210,211,212,采取措施 A,若为其它错误,采取措施C
ON EXCEPTION SET error_num
-- Action C
END EXCEPTION;
ON EXCEPTION IN(-300) SET error_num
-- Action B
END EXCEPTION;
ON EXCEPTION IN(-210, -211, -212) SET error_num
-- Action A
END EXECPTION;
捕捉特定的错误,具体示例:
create procedure todays_orders()
define sql_err int;
define isam_err int;
define error_info char(70);
-- on exception 在存储过程(或者是语句块)的define之后,任何具体语句之前。
on exception set sql_err, isam_err, error_info
call error_routine(sql_err,isam_err,error_info);
end exception;
on exception (-206)
call create_tab();
end exception;
语句
end procedure;
异常捕获:RAISE EXCEPTION
用RAISE EXECPTION 语句模拟异常的产生,该异常可被ON EXECTPION 语句捕获。
格式:
RAISE EXCEPTION SQL错误号, ISAM错误号, 错误文本变量
SQL 错误号和ISAM 错误号均可是SPL 表达式, 且其计算结果是一个常数(错误号)
例子:
RAISE EXCEPTION -99999, 0, --Broke the Rule
异常处理后继续执行
如果有WITH RESUME将继续执行出错行之后语句;
如果没有WITH RESUME 将继续执行下一次循环或下一个语句块。如果没有语句块,则过程将结束。
create procedure get_pick_list(p_order_num int) returning int;
define v_id int;
on exception in (-206) /* -206错误号是数据库中找不到对应的表 */
call log_error (-206)
end exception with resume; /* 2. WITH RESUME将继续执行出错行后面的语句 */
select tabid into v_id from sysname; /* 1.这里出错*/
/*
3. 如果没有WITH RESUME 将继续执行下一次循环或下一个语句块。
如果没有语句块,则过程将结束。
*/
let tabid = 0;
end procedure;
RAISE EXCEPTION示例
异常处理的例子
create function plus(p_date datetime year to fraction(5), p_day float)
returns datetime year to fraction(5)
DEFINE v_date datetime year to fraction(5);
DEFINE v_secend integer;
if p_day > 11574 then
RAISE EXCEPTION -1223;
end if;
let v_second = p_day * 86400;
return p_date + v_second units second;
end function;