WHENEVER actions include CONTINUE, STOP, CALL AND GOTO. The CALL action can invoke built-in or programmer defined functions which will be executed when 4GL encounters the specified event. The CALL handler now can invoke some Querix standard processing functions which handle the events. The following functions can be called within the WHENEVER statement:
The WHENEVER is an easy way to instruct a program what should be done, if an exceptional behavior is spotted, instead of inserting specific 4GL code with the instructions after each statement that may result in an exceptional behavior.
WHENEVER ERROR STOP and WHENEVER ERROR CONTINUE statements check the value of the status built-in variable to define whether an error has occurred.
The default action which 4GL undertakes on encountering any of the exceptional conditions is CONTINUE.
CALL option specifies an event handler, which should be invoked when the WHENEVER condition is met. The event handler can be a programmer defined function, built-in function or a special event handler supported by Querix 4GLNo variables can be passed to the function called in such a way, thus the list of arguments either empty or not should be omitted.
WHENEVER QUIT CALL err_manag
If you use the BEGIN WORK statement in a function called in such a way, always use the WHENEVER ERROR CONTINUE and WHENEVER WARNING CONTINUE before the ROLLBACK WORK statement. Otherwise the program will loop, if the ROLLBACK statement encounters an error or a warning.
You cannot execute a stored procedure by means of the WHENEVER…CALL statement by placing the name of the stored procedure after the CALL keyword. To execute a stored procedure specify a function that contains the EXECUTE PROCEDURE statement after the CALL keyword.
Special event handlers
Querix supports additional special event handlers used with the CALL option:
For exmple,
WHENEVER INTERRUPT CALL EventInterruptFlag
Default event handlers
The system installs default global-level event handlers at start-up which take effect when the corresponding event handlers are not specified explicitly:
event |
default handler |
ARGUMENT ERROR |
EventAbort |
RETURN ERROR |
EventAbort |
UNDEFINED FUNCTION |
EventAbort |
INTERRUPT |
EventTerminate |
QUIT |
EventTerminate |
TERMINATE |
EventTerminate |
HANGUP |
EventTerminate |
FATAL ERROR |
EventTerminate |
ERROR |
EventAbort |
WARNING |
EventAbort |
User event handlers
In addition to the standard processing functions the user may write event processing routines. Such routines always return a value. If they return nonzero then the routine is considered not to have processed the event and it is passed to the next level handler.
FUNCTION work()
WHENEVER TERMINATE CALL mycleanup
INSERT INTO mywork VALUES (my_session_id,'an entry')
CALL mycleanup()
END FUNCTION
FUNCTION mycleanup()
DELETE FROM mywork WHERE id = my_session_id
RETURN 1
END FUNCTION
This would cause the mycleanup function to be called if the program receives a terminate signal, the program would then try the module-level handler for the terminate signal and then (if that did not handle it) the global one.
If the CONTINUE keyword is specified after a WHENEVER condition, 4GL takes no actions when the condition is met. It is the default option for all conditions. Use it to restore the default behavior.
GOTO option can transfer the program control to the specified LABEL statement. The GO TO and GOTO statements are interchangeable. The program control transfer is possible only within the same program block and if the label-name specified after the GOTO statement is the same as the label-name defined by a LABEL statement. In the example below the program control is transferred to the LABEL statement with the name cannot_delete, if a NON FOUND condition occurs:
DELETE * FROM contact
WHERE contact.cont_ord = p_company_id
WHENEVER NOT FOUND GOTO cannot_delete
…
LABEL cannot_delete:
MESSAGE "No such record"
In the cases when you have the WHENEVER statement with the GOTO keyword in one program block (i.e. a FUNCTION program block) and it is followed by other FUNCTION blocks within the same program module, the WHENEVER option is also applied to the subsequent program blocks. If the condition specified in the WHENEVER statement is met during the execution of a subsequent program block (i.e. NOT FOUND condition), 4GL tries to transfer the program control to the label, which is not defined in the current program block. As specified above the GOTO statement can transfer the program control only within the same program block, it cannot transfer control to the LABEL statement which is located in another program block.
You need to redefine the WHENEVER condition. If an SQL statement is processed before it is redefined, an error will occur, if the WHENEVER condition is met. To redefine the condition use another WHENEVER statement (i.e. WHENEVER NOT FOUNT CONTINUE) statesment, or define the corresponding LABEL within each subsequent program block.
RAISE option signals that, in case of an exception, the problem should be handled not by the local function, but by the calling one.
It means that if an exception happens during a function execution after the WHENEVER [ANY] ERROR RAISE statement was encountered, the function execution terminates and the program control returns to the calling routine, i.e., to the statement following the CALL statement. If the calling routine does not contain an error handler, the error is passed further to the parent function.
The RAISE option can be effectively used with the TRY...CATCH statement. You can place the CALL statement to the TRY block and the RAISE option to the invoked function. If any error occurs during the function execution, the program control will pass to the CATCH block.
MAIN
TRY
CALL do_exception(100, 0)
CATCH
CALL foo()
END TRY
END MAIN
FUNCTION do_exception(a, b)
DEFINE a, b, c INTEGER
WHENEVER ANY ERROR RAISE
RETURN a / b
END FUNCTION
FUNCTION foo()
DISPLAY "Exception caught, status: ", STATUS
END FUNCTION
STOP keyword stops the execution of the program when the WHENEVER condition is met. The example below makes 4GL terminate the execution when the database server issues a warning:
WHENEVER WARNING STOP