The ON ERROR clause specifies the statement(s) the host language performs if an error occurs during the execution of the associated RDML statement. You can use the ON ERROR clause in all RDML statements except the DATABASE statement.
1 – Examples
The following programs demonstrate the use of the ON ERROR clause to trap lock errors that occur during execution of the READY statement. The programs start a transaction using the NOWAIT option. This means that execution of the READY statement causes a lock error if anyone else has a lock on the EMPLOYEES relation when you run the programs. In this case, the programs will print the message "database unavailable right now". The programs will try to access the database up to 100 more times before terminating the programs. If the error is not a lock error, the programs print the message "Unexpected Error, Application Terminating". To illustrate this application, build it, and then run it simultaneously from two different terminals.
1.1 – C Example
globalvalue RDB$_LOCK_CONFLICT; globalvalue RDB$_DEADLOCK; #include <stdio.h> DATABASE PERS = FILENAME "PERSONNEL"; void handle_error() { if (RDB$STATUS == RDB$_LOCK_CONFLICT) printf("database unavailable right now\n"); else { printf("Unexpected Error, Application Terminating\n"); RDML$SIGNAL_ERROR(RDB$MESSAGE_VECTOR); } return; } void access_employees() { READY PERS ON ERROR handle_error(); return; END_ERROR; START_TRANSACTION READ_WRITE NOWAIT RESERVING EMPLOYEES FOR EXCLUSIVE WRITE ON ERROR handle_error(); return; END_ERROR; /* perform some read_write operation on the EMPLOYEES relation */ printf ("Accessing EMPLOYEES...\n"); COMMIT; FINISH; } main() { int i; for (i=0; i<=100; i++) access_employees(); }
1.2 – Pascal Example
program onerror (output); DATABASE PERS = FILENAME 'PERSONNEL'; var RDB$_LOCK_CONFLICT : [value,external] integer; i : integer; error : boolean; procedure handle_error; begin if RDB$STATUS = RDB$_LOCK_CONFLICT then writeln ('database unavailable right now') else begin writeln ('Unexpected Error, Application Terminating'); RDML$SIGNAL_ERROR(RDB$MESSAGE_VECTOR) end; end; begin for i := 1 to 100 do begin error := FALSE; READY PERS; START_TRANSACTION READ_WRITE NOWAIT RESERVING EMPLOYEES FOR EXCLUSIVE WRITE ON ERROR handle_error; error := TRUE; END_ERROR; if not error then begin {perform some read_write operation on the EMPLOYEES relation} writeln ('Accessing EMPLOYEES...'); COMMIT; FINISH; end; end; end.
2 – Format
(B)0[mon-error = [4mON[m [4mERROR[m qqwqqq> statement qqqqwqqq> [4mEND_ERROR[m mqqqqqqqqq<qqqqqqqqqj
2.1 – Format arguments
statement Any valid RDML or host language statement to be executed when an RDML error occurs. Use a semicolon (;) at the end of each RDML, Pascal, or C statement.