Set_ingres Constant Values
With these commands, you can perform most of the error-handling functions available in other EQUEL languages. However, the errordisp constant used with the set_ingres statement displays the last Ingres or EQUEL error on the standard output device. If you wish to obtain the text of the last error while at the same time suppressing the default printing of messages, you can use the set_ingres statement in conjunction with the inquire_ingres statement, as follows:
* Silence EQUEL errors messages
## SET_INGRES (ERRORMODE = 0)
## REPLACE employee (empname = "Fred")
* Check to see if an error occurred.
* Assume that "errorvar" is a numeric data item that
* has been declared to EQUEL.
## INQUIRE_INGRES (errorvar = ERRORNO)
IF (errorvar 0) THEN
PERFORM ERROR-PROC
END-IF
. . .
ERROR-PROC.
* Assume that "errorstr" is an alphanumeric data item
* that has been declared to EQUEL.
## INQUIRE_INGRES (errorstr = ERRORTEXT)
DISPLAY "Error text is" errorstr
. . .
You should be aware that the set_ingres method of error handling makes it difficult for the program to detect conversion errors when returning data to the COBOL program in a retrieve loop. This happens because the check for the error condition can only be made at the completion of the retrieve loop.
The following example demonstrates how the set_ingres command may be used to process error message printing:
DATA DIVISION.
WORKING-STORAGE DIVISION.
## 01 REAL-VAR PIC S9(8)V9(6) USAGE COMP-3 VALUE 0.469.
## 01 CON-ERR PIC Z999.
## DECLARE.
PROCEDURE DIVISION.
MAIN.
## INGRES "Equeldb".
## /* Create a temporary table */
## CREATE temp (ccol = c2, icol = i2)
## APPEND TO temp (ccol = "ab", icol = 1)
## /*
## Silence EQUEL error messages and do a replacement
## that causes a conversion error between a c2
## column and a numeric data item.
## */
## SET_INGRES (ERRORMODE = 0)
## REPLACE temp (icol = 2) WHERE temp.ccol = REAL-VAR
## /* Check the EQUEL conversion error and display
## the message. */
## INQUIRE_INGRES (CON-ERR = ERRORNO)
DISPLAY "Conversion error was ", CON-ERR.
## DESTROY temp
* Continue program here.
A more practical example is a handler to catch deadlock errors. For deadlock, a reasonable handling technique in most applications is to suppress the normal error message and simply restart the transaction.
The following EQUEL program executes a Multi-Query Transaction and handles Ingres errors, including restarting the transaction on deadlock.
In this example, Ingres error messages are silenced, using the set_ingres command with the errormode option. When errors do occur, they are tested for deadlock. Note that if deadlock does occur, the transaction is restarted automatically without your knowledge.
IDENTIFICATION DIVISION.
PROGRAM-ID. MQTHANDLER.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
## 01 INGERR PIC S9(4) USAGE COMP.
01 ERR-DISP PIC ZZZZ99 USAGE DISPLAY.
## 01 ERR-TEXT PIC X(80).
01 ING-DEADLOCK PIC S9(4) USAGE COMP.
## DECLARE.
PROCEDURE DIVISION.
MAIN.
* Initialize test data & Ingres table, and silence
* Ingres errors.
PERFORM INIT-DB
* Perform transaction, it includes appending
* and replacing data.
PERFORM PROCESS-DATA
* End multi-statement transaction and Ingres
* interface.
## END TRANSACTION
## DESTROY ITEM
## EXIT
STOP RUN.
INIT-DB.
* Start up Ingres and create a temporary
* test relation.
## INGRES testdb
## CREATE item (name=c10, number=i4)
* Silence Ingres error messages
## SET_INGRES (ERRORMODE = 0).
PROCESS-DATA.
* Begin a multi-query transaction and reset
* deadlock flag.
## BEGIN TRANSACTION.
## APPEND TO item (name = "Barbara", number=38)
PERFORM DEADLOCK
IF (ING-DEADLOCK = 1)
GO TO PROCESS-DATA
END-IF
## REPLACE item (number=39) WHERE item.name="Barbara"
PERFORM DEADLOCK
IF (ING-DEADLOCK = 1)
GO TO PROCESS-DATA
END-IF
## DELETE item WHERE item.number=38
PERFORM DEADLOCK
IF (ING-DEADLOCK = 1)
GO TO PROCESS-DATA
END-IF.
DEADLOCK.
* If the Ingres error is deadlock, the DBMS will
* automatically abort an existing MQT. If the error is
* not deadlock, abort the transaction and the program.
## INQUIRE_INGRES (INGERR = ERRORNO)
IF (INGERR > 0) THEN
IF (INGERR = 4700) THEN
* Deadlock has occurred
MOVE 1 TO ING-DEADLOCK
ELSE
* DISPLAY Ingres error message & abort the
* transaction
MOVE INGERR TO ERR-DISP
DISPLAY "Aborting on Error" ERR-DISP
## INQUIRE_INGRES (ERR-TEXT = ERRORTEXT)
DISPLAY ERR-TEXT
## ABORT
## DESTROY item
## EXIT
STOP RUN
END-IF
ELSE
* Reset deadlock flag
MOVE 0 TO ING-DEADLOCK
END-IF.