informix
INFORMIX-ESQL/C Programmer's Manual
Exception Handling

A Program That Uses Exception Handling

The getdiag.ec program contains exception handling on each of the SQL statements that the program executes. This program is a modified version of the demo1.ec program, which Chapter 1 of this manual explains. The version that this section lists and describes uses the following exception-handling methods:

The whenexp_chk() function displays the error number and the accompanying ISAM error, if one exists. The exp_chk.ec source file contains this function and its exception-handling functions. The getdiag.ec source file (page 11-50) includes the exp_chk.ec file (page 11-53).

Compiling the Program

Use the following command to compile the getdiag program:

The -o getdiag option tells esql to name the executable program getdiag. Without the -o option, the name of the executable program defaults to a.out. For more information on the esql preprocessor command, see Using the esql Command.

Guide to the getdiag.ec File

The annotations in this section primarily describe the exception-handling statements.

Continued on page 11-52

Line 4

Line 4 declares an external global variable to hold the name of the most-recently executed SQL statement. The exception-handling functions use this information (see Lines 169 to 213).

Lines 12 and 13

The WHENEVER SQLERROR statement tells the ESQL/C preprocessor to add code to the program to call the whenexp_chk() function whenever an SQL statement generates an error. The WHENEVER SQLWARNING statement tells the ESQL/C preprocessor to add code to the program to call the whenexp_chk() function whenever an SQL statement generates a warning. The whenexp_chk() function is in the exp_chk.ec file, which line 40 includes.

Line 15

The strcpy() function copies the string "CONNECT stmt" to the global statement variable. If an error occurs, the whenexp_chk() function uses this variable to print the name of the statement that caused the failure.

Lines 17, 23, 25, and 33

Lines 16, 22, 24, and 32 copy the name of the current SQL statement into the statement variable before the DECLARE, OPEN, FETCH, and CLOSE statements, respectively, execute. This action enables the whenexp_chk() function to identify the statement that failed if an error occurs.

Lines 35 and 37

These lines copy the name of the current SQL statement into the statement variable before the FREE and DISCONNECT statements, respectively, execute. The whenexp_chk() function uses the statement variable to identify the statement that failed if an error occurs.

Line 41

The whenexp_chk() function examines the SQLSTATE status variable to determine the outcome of an SQL statement. Because several demonstration programs use the whenexp_chk() function with the WHENEVER statement for exception handling, the whenexp_chk() function and its supporting functions are placed in a separate source file, exp_chk.ec. The getdiag program must include this file with the ESQL/C include directive because the exception-handling functions use ESQL/C statements.

Tip: You should consider putting functions such as whenexp_chk() into a library and include this library on the command line when you compile the ESQL/C program.

The following section describes the exp_chk.ec source file.

Guide to the exp_chk.ec File

The exp_chk.ec file contains exception-handling functions for the ESQL/C demonstration programs. These functions support the following two types of exception handling:

To obtain exception information, the preceding functions use the SQLSTATE variable and the GET DIAGNOSTICS statement. They use SQLCODE only when they need Informix-specific information.

Continued on page 11-56

Lines 1 to 4

These ESQL/C define directives create definitions for the success, warning, NOT FOUND, and runtime error exceptions. Several functions in this file use these definitions instead of constants to determine actions to take for a given type of exception.

Line 5

The statement variable is a global variable that the calling program (which declares it as extern) sets to the name of the most-recent SQL statement.

The whenexp_chk() function displays the SQL statement name as part of the error information (see lines 85 and 92).

Lines 6 to 31

The sqlstate_err() function returns a status of 0, 1, 100, or -1 to indicate if the current exception in SQLSTATE is a success, warning, NOT FOUND, or runtime error, respectively. The sqlstate_err() function checks the first two characters of the global SQLSTATE variable. Because ESQL/C automatically declares the SQLSTATE variable, the function does not need to declare it.

Line 13 checks the first character of the global SQLSTATE variable. This character determines whether the most-recently executed SQL statement has generated a nonerror condition. Nonerror conditions include the NOT FOUND condition (or END OF DATA), success, and warnings. Line 15 checks the second character of the global SQLSTATE variable (SQLSTATE[1]) to determine the type of nonerror condition generated.

The sqlstate_err() function sets err_code to indicate the exception status as follows:

If SQLSTATE[1] contains any character other than '0', '1', or '2', then the most-recently executed SQL statement generated a runtime error. SQLSTATE also indicates a runtime error if SQLSTATE[0] contains some character other than '0'. In either case, line 30 returns a negative one (-1) (which line 4 defines as RTERROR).

Continued on page 11-58

Lines 32 to 80

The disp_sqlstate_err() function uses the GET DIAGNOSTICS statement to obtain diagnostic information about the most-recently executed SQL statement.

Lines 40 to 50 declare the host variables that receive the diagnostic information. The GET DIAGNOSTICS statement copies information from the diagnostics area into these host variables. Line 48 includes a declaration for the SQLSTATE value (called sqlstate_code) because the disp_sqlstate_err() function handles multiple exceptions. The sqlstate_code variable holds the SQLSTATE value for each exception.

Lines 53 to 55 display the values of the SQLSTATE and SQLCODE variables. If SQLSTATE contains "IX000" (an Informix-specific error), SQLCODE contains the Informix-specific error code.

The first GET DIAGNOSTICS statement (lines 56 and 57) stores the statement information in the :exception_count and :overflow host variables. Lines 58 and 59 then display this information.

The for loop (lines 60 to 77) executes for each exception that the most-recently executed SQL statement has generated. The :exception_count host variable, which holds the number of exceptions, determines the number of iterations that this loop performs.

The second GET DIAGNOSTICS statement (lines 62 to 65) obtains the exception information for a single exception. Lines 67 to 70 print out the SQLSTATE value (sqlstate_code) and its corresponding message text. In addition to SQL error messages, disp_sqlstate_err() can display ISAM error messages because the MESSAGE_TEXT field of the diagnostics area also contains these messages. The function uses the MESSAGE_LENGTH value to determine where to place a null terminator in the message string. This action causes only the portion of the message variable that contains text to be output (rather than the full 255-character buffer).

Declare both the class- and the subclass-origin host variables as character buffers of size 255. However, often the text for these variables fills only a small portion of the buffer. Rather than display the full buffer, lines 71 to 73 use the ESQL/C byleng() and stleng() library functions to display only that portion of :class_id that contains text; lines 74 to 76 perform this same task for :subclass_id.

Continued on page 11-59

Lines 81 to 87

The disp_error() function notifies the user of a runtime error. It calls the disp_sqlstate_err() function (line 86) to display the diagnostic information.

Lines 88 to 94

The disp_warning() function notifies the user of a warning. It calls the disp_sqlstate_err() function (line 93) to display the diagnostic information.

Lines 95 to 117

The disp_exception() function handles the display of the exception information. It expects the following three arguments:

stmt is the name of the most-recently executed SQL statement.
sqlerr_code is the code that sqlstate_err() returns to indicate the type of exception encountered.
warn_flg is a flag to indicate whether to display the diagnostic information for a warning.

Lines 102 to 104 handle the SUCCESS and NOData conditions. For either of these cases, the function displays no diagnostic information. Lines 105 to 108 notify the user that a warning has occurred. The function checks the warn_flg argument to determine whether to call the disp_warning() function to display warning information for the most-recently executed SQL statement (lines 137 to 142). Lines 109 to 111 notify the user that a runtime error has occurred. The disp_err() function actually handles display of the diagnostic information.

Continued on page 11-61

Lines 118 to 144

The exp_chk() function is one of three wrapper functions that handle exceptions. It analyzes the SQLSTATE value to determine the success or failure of the most-recent SQL statement. This function is designed to be called explicitly after each SQL statement. This design requires the following features:

The sqlstate_err() function (line 134) determines the type of exception that SQLSTATE contains. The function then calls disp_exception() (line 135) and passes the warn_flg argument to indicate whether to display warning information. To handle a runtime error, the sqlstate_err() function calls the exit() system function (lines 136 to 141) to terminate the program. This behavior is the same as what the whenexp_chk() function (see lines 170 to 214) provides for runtime errors.

The dyn_sql sample program (see The dyn_sql Program) also uses exp_chk() to handle exceptions.

Continued on page 11-64

Lines 145 to 168

The exp_chk2() function is the second of the three exception-handling wrapper functions in the exp_chk.ec file. It performs the same basic task as the exp_chk() function. Both functions are designed to be called after each SQL statement and both return a status code. The only difference between the two is in the way they respond to runtime errors. The exp_chk() function calls exit() to terminate the program (line 140), while the exp_chk2() function returns the SQLCODE value to the calling program (lines 165 to 166).

The exp_chk2() function returns SQLCODE rather than SQLSTATE to allow the program to check for particular Informix-specific error codes. A possible enhancement might be to return both the SQLSTATE and SQLCODE values.

The dyn_sql sample program, described on page 16-54, also uses exp_chk2() to handle exceptions.

Lines 169 to 213

The whenexp_chk() function is the third exception-handling wrapper function in the exp_chk.ec file. It too analyzes the SQLSTATE values and uses the GET DIAGNOSTICS statement for exception handling. However, this function is designed to be called with the following WHENEVER statements:

The WHENEVER statement imposes the following restrictions on the design of the whenexp_chk() function:

The getdiag sample program, which this chapter describes, uses whenexp_chk() to handle exceptions. See lines 11 and 12 of the getdiag.ec file on page 11-50.

The sqlstate_err() function (line 185) returns an integer that indicates the success of the most-recently executed SQL statement. This return value is based on the SQLSTATE value.

Lines 186 to 198 display a special line to bring attention to the exception information that was generated. The disp variable is a flag that indicates whether to display exception information. The function displays exception information for warnings (WARNING) and runtime errors (RTERROR) but not for other exception conditions. The calls to the printf() function (lines 189 and 195) display the name of the SQL statement that generated the warning or error. A global variable (called statement) must store this statement name because the function cannot receive it as an argument.

The disp_sqlstate_err() function (lines 199 and 200) displays the information that the diagnostics area contains only if SQLSTATE indicates a warning or a runtime error (disp = 1).

Lines 201 to 206 handle a runtime error. They notify the user of the program termination and then use the exit() system call (line 205) to terminate the program. The call to the disp_sqlstate_err() function (line 200) has already displayed information about the cause of the runtime error.


INFORMIX-ESQL/C Programmer's Manual, Version 9.21
Copyright © 1999, Informix Software, Inc. All rights reserved