We have a Chinese version(http://scn.sap.com/community/chinese/hana/blog/2014/04/02/sap-hana-sqlscript-procedure%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86) of this document.
For SQL procedure using SQLScript, SAP HANA provides corresponding methods of exception handling. There are three tools can be used: EXIT HANDLER, CONDITION, SIGNAL or RESIGANL.
An example using EXIT HANLEDR shows as follows.
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;
When invoking this procedure, an exception of violating unique constraint will be thrown, for inserting the same content on primary key. Then the invocation well be suspended, and the subsequent operations will not be executed. After suspending the procedure, the action operations of EXIT HANDLER will be executed.
Notice: We can use "::SQL_ERROR_CODE","::SQL_ERROR_MESSAGE" to get the SQL ERROR CODE and related error message of the caught exception.
EXIT HANDLER
When declare an EXIT HANDLER in SQLScript Procedure, the syntax shows as below.
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>
We can declare an EXIT HANDLER to handle exceptions of the given SQL ERROR CODE or user defined condition in SQL procedures and provide the subsequent operations after the exception is thrown.
Notice:
SAP HANA provides common SQL error code:
http://help.sap.com/saphelp_hanaplatform/helpdata/en/20/a78d3275191014b41bae7c4a46d835/content.htm
or check“SAP HANA SQL and System Views Reference”->1.10 SQL Error Codes
CONDITION
You can declare a CONDITION in SQL procedure to define a condition which contains a SAP HANA error code or used-defined error code and name it. Then you can declare an EXIT HANDLER to handle exception of this condition, or use SIGNAL or RESIGNAL to throw an exception of a condition containing a user-defined error code.
The syntax of CONDITION declaration:
DECLARE <condition name> CONDITION [ FOR <sql_error_code> ];<sql_error_code> ::= SQL_ERROR_CODE <numeric_literal>
SIGNAL/RESIGNAL
SIGNAL or RESIGNAL can be used to throw exception in SQL procedure. But here exception only represents used-defined error, whose error code is between 10000 and 19999.
The difference between SIGNAL and RESIGNAL is that when using SIGNAL, you must point out the SQL ERROR CODE or CONDITION of the exception. But RESIGNAL can be used in the action part of an EXIT HANDLER all alone. That is to say, RESIGNAL can be used to throw exception of the EXIT HANDLER catches to the caller. A user-defined exception can be catch by the corresponding EXIT HANDLER, or caught by the caller, same as an exception contains error code.
The syntax of using SINGAL or 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>
Examples
1.General exception handling
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.Error code exception handling
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;
The error message of SQL ERROR CODE 1299 is ”No data found”.
3.Conditional Exception Handling
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.Throw an exception using 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.Throw an exception using 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.When using EXIT HANLDER, related tables can be used to store the exception information.
CREATETABLE ERROR_LOG (ERROR_CODE VARCHAR(5), ERROR_MSG VARCHAR(200), TIME_STAMP TIMESTAMP); CREATE PROCEDURE 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;