Exceptions and Exception Handling
On this page
This topic describes exceptions and exception handling in SingleStore Procedural SQL (PSQL) user-defined scalar-valued functions (UDFs) and stored procedures (SPs).
Exception Types
UDFs and SPs raise exceptions when errors occur during execution.
Two kinds of exceptions can be raised:
-
An internal exception, which is a predefined exception generated by SingleStore
-
A user-defined exception, which is defined by the user in a UDF or SP
The following sections describe each kind of exception and how to handle exceptions in your UDF or SP.
Exception Handling Syntax
If you want to catch an exception, you can use a Statement Block containing an exception handling section beginning with the EXCEPTION keyword.EXCEPTION:
statement_block:
[ DECLARE variable_list ] [ ...n ]
BEGIN
statement_list
[ EXCEPTION
when_clause_list ]
END;
when_clause_list:
when_clause [ ...n ]
when_clause:
WHEN exception_type THEN statement_list
exception_
An exception_ is the name of a built-in server error type.
The keyword OTHERS can also be used as an exception_.OTHERS matches all exceptions.
statement_
A list of one or more statements terminated by semicolons.
Internal Exceptions
Internal exceptions are defined by SingleStore, and they are raised when a function or procedure errors under a wide variety of conditions.
Here are some possible internal exceptions:
|
Exception Name |
Description |
Scenario When Exception is Thrown |
|---|---|---|
|
|
The Scalar function did not return any value. |
This exception is thrown when a |
|
|
Column name does not exist. |
A column that does not exist in a table is referenced in a query. |
|
|
Table already exists. |
While creating a table, a table with the same name already exists. |
|
|
Table does not exist. |
A table that does not exist is referenced in a query. |
|
|
Table does not exist. |
A table that does not exist is referenced in a query. |
|
|
Duplicate key error. |
A duplicate value is entered for a column with a key constraint. |
|
|
Column count does not match value count. |
The number of columns in a table and the number of values specified in the query are not the same. |
|
|
Issue with parsing dynamic SQL. |
There is an error in the SQL statement. |
|
|
Cannot find file, usually in |
Either the file does not exist or the file path is incorrect. |
Consider the following example, where table t contains two entries and id is defined as a PRIMARY KEY:
CREATE TABLE t(id INT PRIMARY KEY, str VARCHAR(255));CREATE TABLE t_errors(dt DATETIME, id INT, str VARCHAR(255));INSERT t VALUES (0, "foo"), (1, "bar");
The following procedure attempts to insert a row with a duplicate primary key, which raises the ER_ exception.t_ table instead:
DELIMITER //CREATE OR REPLACE PROCEDURE insert_handle_exception(id INT, str VARCHAR(255)) ASBEGINSTART TRANSACTION;INSERT INTO t VALUES (1, str);COMMIT;EXCEPTIONWHEN ER_DUP_ENTRY THENROLLBACK;START TRANSACTION;INSERT INTO t_errors VALUES (current_timestamp(), id, str);COMMIT;END //DELIMITER ;
When insert_ is called, the error-handling behavior successfully inserts the contents of the row, and the current time, into the t_ table instead:
CALL insert_handle_exception(1, "baz");
Query OK, 0 rows affected (0.26 sec)SELECT * FROM t_errors;
+---------------------+------+------+
| dt | id | str |
+---------------------+------+------+
| 2017-09-26 22:33:22 | 1 | baz |
+---------------------+------+------+SELECT * FROM t;
+----+------+
| id | str |
+----+------+
| 0 | foo |
| 1 | bar |
+----+------+The use of START TRANSACTION, COMMIT, and ROLLBACK above is not really necessary in this simple example, but it does illustrate how you can use transaction control statements in conjunction with exception handling.
User-Generated Exceptions
Users can generate their own exceptions through the RAISE USER_ statement.USER_ is a function that takes a string as an argument.RAISE statement raises an ER_ exception.
The RAISE keyword by itself can be used inside an EXCEPTION block to re-raise the currently caught exception.
When in an EXCEPTION block, the EXCEPTION_ function can be used to obtain the message that was passed into USER_ for the currently caught exception.EXCEPTION_ follows.
In the following example, the attempt() procedure raises three possible exceptions:
-
A user exception with message "rollback" (when i<=7).
-
A user exception with message "retry" (when i<=3).
-
A bad null typecast (when 3 < i < 7).
The attemptWithRetry() procedure calls attempt() and does the following:
-
On receiving a user exception with a "retry" error message, retries the call to
attempt(). -
On receiving a user exception with a "rollback" error message, re-raises the exception.
-
On receiving a different type of error (the null typecast in this example), raises a user exception with the message "other exception".
DELIMITER //CREATE OR REPLACE PROCEDURE attempt() ASDECLARE i INT; j INT NOT NULL = 0;BEGINi = now() % 10;IF i >= 7 THENRAISE user_exception("rollback"); -- line 6ELSIF i <= 3 THEN -- line 7j = NULL; -- line 8 force an exception by assigning NULL to a NOT NULL typeEND IF;RAISE user_exception("retry"); -- line 10END //DELIMITER ;
DELIMITER //CREATE OR REPLACE PROCEDURE attemptWithRetry() ASDECLARE i INT;BEGINWHILE true LOOPBEGINSTART TRANSACTION;CALL attempt(); -- line 7EXCEPTIONWHEN ER_USER_RAISE THEN -- line 10ROLLBACK; -- line 11IF REGEXP_INSTR(EXCEPTION_MESSAGE(), "retry") THENi = sleep(1);CONTINUE;ELSIF REGEXP_INSTR(EXCEPTION_MESSAGE(), "rollback") THENRAISE;END IF;WHEN OTHERS THENROLLBACK; -- line 19RAISE user_exception("other exception"); -- line 20END;COMMIT;EXIT;END LOOP;END //DELIMITER ;
The attemptWithRetry() procedure illustrates the use of OTHERS to catch exceptions not explicitly named in a WHEN clause.attempt(), the assignment j = NULL is tried; this assignment always fails because j is declared as NOT NULL.WHEN OTHERS.
When attemptWithRetry() is called, the expected results are:
-
A user exception with the message "rollback".
-
A user exception with the message "other exception".
-
Either of these exceptions may display a call stack showing multiple retries.
Call attemptWithRetry() multiple times to see the different results.
In the following call of attemptWithRetry(), attempt() tries the invalid NULL assignment and a system failure is generated which is caught with OTHERS.
CALL attemptWithRetry();
ERROR 2242 (HY000): Unhandled exception
Type: ER_USER_RAISE
Message: other exception
Callstack:
#0 Line 7 in `db`.`attemptWithRetry`Last modified: March 5, 2026