Not an engine assertion, not like "I've got an assertion! What should I do?", but one of my own...
Answer: Pick a number, any number (as long as it's somewhere between 99000 to 99999, let's say 99002) and then use DECLARE EXCEPTION and SIGNAL:
Question: How do I force an exception when my SQL code hits an "impossible" situation?
In other words, how do I code an assertion test inside my stored procedure or trigger?
IF [pigs were seen aloft] THEN
BEGIN
DECLARE @exception EXCEPTION FOR SQLSTATE '99002';
SIGNAL @exception;
END;
END IF;
That's all there is to it: A single chunk of code inserted into your procedure:- No need to DECLARE the exception somewhere else,
that's what the local BEGIN block is for.
- You can even use the same name "@exception" over and over again in the same procedure,
[repeat refrain]
that's what the local BEGIN block is for.
CREATE PROCEDURE p()
BEGIN
DECLARE @x INTEGER;
SET @x = NULL;
IF @x IS NULL THEN
BEGIN
DECLARE @exception EXCEPTION FOR SQLSTATE '99002';
SIGNAL @exception;
END;
END IF;
END;
Here's what happens in dbisql:CALL p(); Could not execute statement. User-defined exception signaled SQLCODE=-297, ODBC 3 State="99002" Line 1, column 1 CALL p()The number you pick doesn't have to be unique, that's up to you... you can use 99002 all over the place if you don't mind the aggro of not knowing where it came from.
Here's a sample that includes code for capturing and recording exceptions; in this case, the 99xxx numbers are only unique within the stored procedure because other logic takes care of identifying the procedure:
DECLARE @diagnostic_location VARCHAR ( 20 );
DECLARE @sqlcode INTEGER;
DECLARE @sqlstate VARCHAR ( 5 );
DECLARE @errormsg VARCHAR ( 32767 );
...
SELECT ...
IF SQLCODE <> 0 THEN
BEGIN
DECLARE @exception EXCEPTION FOR SQLSTATE '99034';
SIGNAL @exception;
END;
END IF;
...
UPDATE ...
IF @@ROWCOUNT <> 1 THEN
BEGIN
DECLARE @exception EXCEPTION FOR SQLSTATE '99035';
SIGNAL @exception;
END;
END IF;
...
INSERT ...
IF @@ROWCOUNT <> 7 THEN
BEGIN
DECLARE @exception EXCEPTION FOR SQLSTATE '99036';
SIGNAL @exception;
END;
END IF;
...
EXCEPTION
WHEN OTHERS THEN
SELECT SQLCODE, SQLSTATE, ERRORMSG()
INTO @sqlcode, @sqlstate, @errormsg;
IF @sqlstate LIKE '99___' THEN
SET @errormsg = STRING ( 'Internal error ', @sqlstate );
END IF;
CALL rroad_exception ( STRING (
@diagnostic_location, '(210eh1)',
' SQLCODE = ', @sqlcode,
', SQLSTATE = ', @sqlstate,
', ERRORMSG() = ', @errormsg ) );
RESIGNAL;
For more information about handling exceptions, see these earlier posts:Tip: The All-Encompassing Try-Catch
Refactoring Foxhound: Logging Exceptions
Dump and Continue
No comments:
Post a Comment