Every program language has its own way of handling error conditions. The techniques range from "checking the error code" after a transaction or statement, to developing error or condition handlers.

In SQL PL, the error processing is usually done through the use of condition handlers. This simplifies development since rarely used error handling code can be placed into separate blocks of code. However, this technique of encapsulating error code in a condition handler isn't always used by developers, especially those coming from environments where this technique is not available.

The generic error handler approach, where all error information is saved in local variables, is usually a result of porting a stored procedure from some other database platform. An example of this technique is shown below:

DECLARE SQLCODE INT;
DECLARE SQLSTATE CHAR(5);
DECLARE RC_SQLCODE INT DEFAULT 0;
DECLARE RC_SQLSATTE CHAR(5) DEFAULT '00000';
DECLARE CONTINUE HANDLER FOR
  SQLEXCEPTION,
  SQLWARNING,
  NOT FOUND
VALUES (SQLCODE, SQLSTATE) INTO
  RC_SQLCODE, RC_SQLSTATE;
UPDATE EMPLOYEE SET SALARY=50000 WHERE EMPNO=20;
IF (RC_SQLCODE <> 0) THEN
SIGNAL SQLSTATE '78001'
       SET MESSAGE_TEXT='ERROR FINDING EMPLOYEE';
END IF;

This technique is expensive from an SQL PL perspective since the condition handler is being invoked for almost all of the SQL statements. In addition, the NOT FOUND condition is actually a warning, and can be checked explicitly rather than using a CONTINUE HANDLER.

Instead of using the RC_SQLCODE in the body of the procedure, it can be replaced with the native SQLCODE value:

UPDATE EMPLOYEE SET SALARY=50000 WHERE EMPNO=20;
IF (SQLCODE = 100) THEN
SIGNAL SQLSTATE '78001'
       SET MESSAGE_TEXT='EMPLOYEE NOT FOUND';
END IF;

Any unexpected errors should be placed into the exception handler rather than using local variables to test for the type of error. This will result in much more readable code and reduce the possibility of errors if you forget to zero out the temporary return code variables.

The exception handler would be modified in the previous example to eliminate the NOT FOUND exception and to return an error directly within the exception handler:

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SIGNAL SQLSTATE '78001'
       SET MESSAGE_TEXT='ERROR UPDATING RECORD';

The two variables, SQLCODE and SQLSTATE, must be defined within the routine and are reserved for DB2's use. These are set after each SQL statement is executed. The routine would now be updated to include the new condition handler, along with a direct check against the SQLCODE to determine whether a record was updated.

DECLARE SQLCODE INT;
DECLARE SQLSTATE CHAR(5);
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SIGNAL SQLSTATE '78001'
       SET MESSAGE_TEXT='ERROR UPDATING RECORD';
UPDATE EMPLOYEE SET SALARY=50000 WHERE EMPNO=20;
IF (SQLCODE = 100) THEN
SIGNAL SQLSTATE '78001'
       SET MESSAGE_TEXT='EMPLOYEE NOT FOUND';
END IF;