对于使用SQlScript 的存储过程,SAP HANA提供了相应的异常处理的方法。分别包含几三个相关的工具:EXIT HANDLER, CONDITION, SIGNAL或 RESIGNAL。
使用EXIT HANLDER的例子如下所示:
CREATETABLE MYTAB (I INTEGERPRIMARYKEY); CREATE PROCEDURE MYPROC1 AS BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT ::SQL_ERROR_CODE, ::SQL_ERROR_MESSAGE FROM DUMMY; INSERT INTO MYTAB VALUES (1); INSERT INTO MYTAB VALUES (1); -- expected unique violation error: 301 END;
调用这个存储过程时,因为主键的限制,插入同样的内容,会因违反唯一性约束而引发异常。使得这个存储过程因为异常而中止,后续操作不会执行。在存储过程调用中止后,再执行EXIT HANDLER中的操作。
注:可以使用”::SQL_ERROR_CODE”,”::SQL_ERROR_MESSAGE”来获取当前异常的SQL ERROR CODE及相应的错误信息。
EXIT HANDLER
在SQLScript Procedure中声明EXIT HANDLER,相应语法为:
DECLARE EXIT HANDLER FOR <proc_condition_value_list> <proc_stmt>;
<proc_condition_value_list> ::= <condition_value> [ { <comma> <condition_value> }... ]
<condition_value> ::= <sql_error_code> | <condition_name> | SQLEXCEPTION
<sql_error_code> ::= SQL_ERROR_CODE <numeric_literal>
可以在存储过程中,声明针对特定的SQL ERROR CODE或者用户自定义的条件的EXIT HANDLER。并指明当抛出异常中止后,要执行的语句。
注:
SAP HANA数据库提供常用的SQL error code:
http://help.sap.com/saphelp_hanaplatform/helpdata/en/20/a78d3275191014b41bae7c4a46d835/content.htm
或查看“SAP HANA SQL and System Views Reference”-> SQL Error Codes
CONDITION
在SQLScript Procedure中可以声明CONDITION,来定义包含一个SAP HANA错误代码或者用户自定义的错误代码的条件,并为其命名。则后续可以声明针对处理这个条件的EXIT HANDLER,或者可以使用SIGNAL 或RESIGNAL 显示抛出只包含用户自定义错误代码的条件的异常。
声明CONDITION 的语法为:
DECLARE <condition name> CONDITION [ FOR <sql_error_code> ];
<sql_error_code> ::= SQL_ERROR_CODE <numeric_literal>
SIGNAL/RESIGNAL
使用SINGAL或者RESINGAL语句来显示地抛出异常。SINGAL和RESINGAL只能抛出用户自定义的错误类型(即指错误代码 SQL ERROR CODE在10000~19999之间)。
SIGNAL和RESIGNAL的区别,SIGNAL使用时必须指明SQL ERROR CODE或者CONDITION的名字,RESIGANL可以单独在EXIT HANDLER的action语句中使用,即可以使用RESIGNAL将EXIT HANDLER捕获的异常再抛出给上一级调用者。同SAP HANA的错误代码所对应的异常一样,一个用户自定义的异常可以被它所在的存储过程中相关的exit handler捕获处理,也可以被上层调用的存储过程所捕获处理。
使用SINGAL或RESIGNAL的语法为:
SIGNAL <signal_value> [<set_signal_information>] ;
RESIGNAL [<signal_value>] [<set_signal_information>];
<signal_value> ::= <condition_name> | <sql _error_code>
<set_signal_information> ::= SET <signal_information_item>
<signal_information_item> ::= MESSAGE_TEXT <equals operator> <simple_value_specification>
<simple_value_specification> ::= <procedure_expression>
使用举例
1.普通异常处理
CREATETABLE MYTAB (I INTEGER PRIMARYKEY); CREATE PROCEDURE MYPROC AS BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT ::SQL_ERROR_CODE, ::SQL_ERROR_MESSAGE FROM DUMMY; INSERT INTO MYTAB VALUES (1); INSERT INTO MYTAB VALUES (1); -- expected unique violation error: 301 -- will not be reached END; CALL MYPROC;
2.指定特定SQL ERROR CODE的异常处理
CREATETABLE MYTAB (I INTEGERPRIMARYKEY); CREATE PROCEDURE MYPROC AS BEGIN DECLARE myVar INT; DECLARE EXIT HANDLER FOR SQL_ERROR_CODE 1299 SELECT ::SQL_ERROR_CODE, ::SQL_ERROR_MESSAGE FROM DUMMY; SELECT I INTO myVar FROM MYTAB; --NO_DATA_FOUND exception END; CALL MYPROC;
SQL ERROR CODE 1299对应的错误为”No data found”.
3.指定特定CONDITION的异常处理
CREATETABLE MYTAB (I INTEGERPRIMARYKEY); CREATE PROCEDURE MYPROC AS BEGIN DECLARE MYCOND CONDITION FOR SQL_ERROR_CODE 301; DECLARE EXIT HANDLER FOR MYCOND SELECT ::SQL_ERROR_CODE, ::SQL_ERROR_MESSAGE FROM DUMMY; INSERT INTO MYTAB VALUES (1); INSERT INTO MYTAB VALUES (1); -- expected unique violation error: 301 -- will not be reached END; CALL MYPROC;
4.使用SIGNAL抛出异常
CREATEPROCEDURE MYPROC AS BEGIN DECLARE MYCOND CONDITION FOR SQL_ERROR_CODE 10001; DECLARE EXIT HANDLER FOR MYCOND SELECT ::SQL_ERROR_CODE, ::SQL_ERROR_MESSAGE FROM DUMMY; SIGNAL MYCOND SET MESSAGE_TEXT = 'my error'; -- will not be reached END; CALL MYPROC;
5.使用RESIGNAL 抛出异常
CREATEPROCEDURE MYPROC AS BEGIN DECLARE MYCOND CONDITION FOR SQL_ERROR_CODE 10001; DECLARE EXIT HANDLER FOR MYCOND RESIGNAL; SIGNAL MYCOND SET MESSAGE_TEXT = 'my error'; -- will not be reached END; CALL MYPROC;
6.对于EXIT HANDLER的使用,可用使用先关表格来保存异常信息。
CREATETABLE ERROR_LOG
(ERROR_CODE VARCHAR(5),
ERROR_MSG VARCHAR(200),
TIME_STAMP TIMESTAMP);
CREATEPROCEDURE MYPROC AS BEGIN DECLARE MYCOND CONDITION FOR SQL_ERROR_CODE 10001; DECLARE EXIT HANDLER FOR MYCOND signal mycond set message_text = 'error'; SIGNAL MYCOND; -- will not be reached END; CREATE PROCEDURE MYPROC1 AS BEGIN DECLARE EXIT HANDLER FOR sqlexception INSERT INTO ERROR_LOG VALUES(::SQL_ERROR_CODE, ::SQL_ERROR_MESSAGE,CURRENT_TIMESTAMP); CALL MYPROC; END; CALL MYPROC1;
查询ERROR_LOG表中的信息:
想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!
转载本文章请注明作者和出处<http://scn.sap.com/community/chinese/hana/blog/2014/04/01/sap-hana-sqlscript-procedure%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86>,请勿用于任何商业用途。