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

Exception Handling with the sqlca Structure

An alternative way to obtain diagnostic information is through the SQL Communications Area. When an SQL statement executes, the database server automatically returns information about the success or failure of the statement in a C structure that is called sqlca. To obtain exception information, your ESQL/C program can access the sqlca structure or the SQLCODE variable as follows:

The next three sections describe how to use the SQLCODE variable and the sqlca structure to perform exception handling. These sections cover the following topics:

Fields of the sqlca Structure

Figure 11-13 contains the declaration of the sqlca structure from the sqlca.h header file. The ESQL/C preprocessor automatically includes the sqlca.h header file in an ESQL/C program.

Figure 11-13
Declaration of sqlca in the sqlca.h Header File

Figure 11-14 illustrates the fields of the sqlca structure.

Figure 11-14
Fields of the sqlca Structure

Field Type Value Value Description
sqlcode int4 0 Indicates success.
>=0, < 100 After a DESCRIBE statement, represents the type of SQL statement that is described.
100 After a successful query that returns no rows, indicates the NOT FOUND condition. NOT FOUND can also occur in an ANSI-compliant database after an INSERT INTO/SELECT, UPDATE, DELETE, or SELECT... INTO TEMP statement fails to access any rows. For more information, see NOT FOUND in SQLSTATE.
<0 Error code.
sqlerrm character (72) Contains the error message parameter. This field does not contain a full error message, just the parameter that is found within an error message. If an error message has no parameter, this field is blank. For more information, see page 11-38.
sqlerrp character (8) Internal use only.
sqlerrd array of 6
int4s
[0] After a successful PREPARE statement for a SELECT, UPDATE, INSERT, or DELETE statement, or after a select cursor is opened, this field contains the estimated number of rows affected.
[1] When SQLCODE contains an error code, this field contains either zero or an additional error code, called the ISAM error code, that explains the cause of the main error. After a successful insert operation of a single row, this field contains the value of any SERIAL value generated for t hat row.
[2] After a successful multirow insert, update, or delete operation, this field contains the number of rows that were processed. After a multirow insert, update, or delete operation that ends with an error, this field contains the number of rows that were successfully processed before the error was detected.
[3] After a successful PREPARE statement for a SELECT, UPDATE, INSERT, or DELETE statement, or after a select cursor was opened, this field contains the estimated weighted sum of disk accesses and total rows processed.
[4] After a syntax error in a PREPARE, EXECUTE IMMEDIATE, DECLARE, or static SQL statement, this field contains the offset in the statement text where the error was detected.
[5] After a successful fetch of a selected row, or a successful insert, update, or delete operation, this field contains the rowid (physical address) of the last row that was processed. Whether this rowid value corresponds to a row that the database server returns to the user depends on how the database server processes a query, particularly for SELECT statements.
sqlwarn array of 8
characters
When Opening a Database:
sqlwarn0 Set to W when any other warning field is set to W. If blank, others need not be checked.
sqlwarn1 Set to W when the database now open uses a transaction log.
sqlwarn2 Set to W when the database now open is ANSI compliant.
sqlwarn3 Set to W when the database server is any server other than INFORMIX-SE.
sqlwarn4 Set to W when the database server stores the FLOAT data type in DECIMAL form (done when the host system lacks support for FLOAT data types).
sqlwarn5 Reserved.
sqlwarn6 Set to W when the application is connected to a database server that is running in secondary mode. The database server is a secondary server in a data-replication pair (the database server is available only for read operations).
sqlwarn7 Set to W when client DB_LOCALE does not match the database locale. For more information, see the chapter on ESQL/C in the Informix Guide to GLS Functionality.
sqlwarn array of 8
characters
All Other Operations:
sqlwarn0 Set to W when any other warning field is set to W. If blank, other fields in sqlwarn need not be checked.
sqlwarn1 Set to W if a column value is truncated when it is fetched into a host variable using a FETCH or a SELECT...INTO statement. On a REVOKE ALL statement, set to W when not all seven table-level privileges are revoked.
sqlwarn2 Set to W when a FETCH or SELECT statement returns an aggregate function (SUM, AVG, MIN, MAX) value that is null.
sqlwarn3 On a SELECT...INTO, FETCH...INTO, or EXECUTE...INTO statement, set to W when the number of items in the select list is not the same as the number of host variables given in the INTO clause to receive them. On a GRANT ALL statement, set to W when not all seven table-level privileges are granted.
sqlwarn4 Set to W after a DESCRIBE statement if the prepared statement contains a DELETE statement or an UPDATE statement without a WHERE clause.
sqlwarn5 Set to W following execution of a statement that does not use ANSI-standard SQL syntax (provided the DBANSIWARN environment variable is set).
sqlwarn6 Set to W when a data fragment (a dbspace) has been skipped during query processing (when the DATASKIP feature is on).
sqlwarn7 Reserved.

Using the SQLCODE Variable

The SQLCODE variable is an int4 that indicates whether the SQL statement succeeded or failed. The ESQL/C header file, sqlca.h, declares SQLCODE as a global variable. Since the ESQL/C preprocessor automatically includes sqlca.h in an ESQL/C program, you do not need to declare SQLCODE.

When the database server executes an SQL statement, the database server automatically updates the SQLCODE variable as follows:

  1. The database server stores the exception value in the sqlcode field of the sqlca structure.
  2. ESQL/C copies the value of sqlca.sqlcode to the global SQLCODE variable.
  3. Tip: For readability and brevity, use SQLCODE in your ESQL/C program in place of sqlca.sqlcode.

The SQLCODE value can indicate the following types of exceptions:

SQLCODE = 0 Success
SQLCODE = 100 NOT FOUND condition
SQLCODE < 0 Runtime error

For information about the values of SQLCODE (and sqlca.sqlcode) and their corrective actions, use the finderr or Find Error utility or view Informix Error Messages in Answers OnLine. For information about how to handle these exceptions, see Checking for Exceptions with sqlca.

The following sections provide additional information about SQLCODE.

SQLCODE in Pure C Modules

To return the same values that the SQLCODE status variable in ESQL/C modules returns, you can use SQLCODE in pure C modules (modules with the .c extension) that you link to an ESQL/C program. To use SQLCODE in a pure C module, declare SQLCODE as an external variable, as follows:

SQLCODE and the exit() Call

To return an error code to a parent process, do not attempt to use the SQLCODE value as an argument to the exit() system call. When ESQL/C passes back the argument of exit() to the parent, it passes only the lower eight bits of the value. Since SQLCODE is a four-byte (long) integer, the value that ESQL/C returns to the parent process might not be what you expect.

To pass error information between processes, use the exit value as an indication that some type of error has occurred. To obtain information on the actual error, use a temporary file, a database table, or some form of interprocess communication.

SQLCODE After a DESCRIBE Statement

The DESCRIBE statement returns information about a prepared statement before the statement executes. It operates on a statement ID that a PREPARE statement has previously assigned to a dynamic SQL statement.

After a successful DESCRIBE statement, the database server sets SQLCODE (and sqlca.sqlcode) to a nonnegative integer value that represents the type of SQL statement that DESCRIBE has examined. The sqlstype.h header file declares constant names for each of these return values. For a list of possible SQLCODE values after a DESCRIBE statement, see Determining the Statement Type.

Because the DESCRIBE statement uses the SQLCODE field differently than any other statement, you might want to revise your exception-handling routines to accommodate this difference.

Checking for Exceptions with sqlca

After an SQL statement executes, the sqlca structure can indicate one of the four possible conditions that Figure 11-15 shows.

Figure 11-15
Exceptions That the sqlca Structure Returns

Exception Condition sqlca Value
Success SQLCODE (and sqlca.sqlcode) = 0
Success, but no rows found SQLCODE (and sqlca.sqlcode) = 100
Success, but warnings generated sqlca.sqlwarn.sqlwarn0 = 'W' To indicate specific warning:
  • One of sqlwarn1 to sqlwarn7 in the sqlca.sqlwarn structure is also set to W
  • Failure, runtime error generated SQLCODE (and sqlca.sqlcode) < 0

    For a general introduction to these four conditions, see Types of Database Exceptions. The following sections discuss how sqlca indicates each condition.

    Success in sqlca

    When the database server executes an SQL statement successfully, it sets SQLCODE (sqlca.sqlcode) to zero (0). The database server might also set one or more of the following informational fields in sqlca after a successful SQL statement:

    For more information on these additional fields, see Fields of the sqlca Structure. In addition, the SQLCODE value for some SQL statements has special meaning. For more information, see Using the SQLCODE Variable.

    NOT FOUND in SQLCODE

    When a SELECT or FETCH statement encounters NOT FOUND (or END OF DATA), the database server sets SQLCODE (sqlca.sqlcode) to 100. Figure 11-16 lists conditions that cause SQL statements to yield NOT FOUND.

    Figure 11-16
    SQLCODE Values That Are Set When SQL Statements Do Not Return Any Rows

    SQL Statement Where SQLCODE Gets the Indicated Result Result for ANSI-Compliant Database Result for Non-ANSI-Compliant Database
    FETCH statement: the last qualifying row has already been returned (the end of data was reached). 100 100
    SELECT statement: no rows match the SELECT criteria. 100 100
    DELETE and DELETE...WHERE statement (not part of multistatement PREPARE): no rows match the DELETE criteria. 100 0
    INSERT INTO tablename SELECT statement (not part of multistatement PREPARE): no rows match the SELECT criteria. 100 0
    SELECT... INTO TEMP statement (not part of multistatement PREPARE): no rows match the SELECT criteria. 100 0
    UPDATE...WHERE statement (not part of multistatement PREPARE): no rows match the UPDATE criteria. 100 0

    Figure 11-16 on page 11-35 shows that what the NOT FOUND condition generates depends, in some cases, on whether the database is ANSI compliant.

    In the following example, the INSERT statement inserts into the hot_items table any stock item that has an order quantity greater than 10,000. If no items have an order quantity that great, the SELECT part of the statement fails to insert any rows. The database server returns 100 in an ANSI-compliant database and 0 if the database is not ANSI compliant.

    For readability, use the constant SQLNOTFOUND for the END OF DATA value of 100. The sqlca.h header file defines the SQLNOTFOUND constant. The following comparison checks for the NOT FOUND and END OF DATA conditions:

    Warnings in sqlca.sqlwarn

    When the database server executes an SQL statement successfully, but encounters a warning condition, it updates the following two fields in the sqlca.sqlwarn structure:

    These warnings are Informix specific. Figure 11-14 on page 11-29 contains two sets of warning conditions that can occur in the fields of the sqlca.sqlwarn structure. The first set of warnings, shown in Figure 11-14, occur after the database server opens a database or establishes a connection. For more information on these conditions, see Determining Features of the Database Server. The second set of warnings are for conditions that can occur as a result of other SQL statements.

    To test for warnings, check whether the first warning field (sqlwarn0) is set to W. Once you determine that the database server has generated a warning, you can check the values of the other fields in sqlca.sqlwarn to identify the specific condition. For example, if you want to find out what kind of database a CONNECT statement has opened, you can use the code that Figure 11-17 shows.

    
    

    Figure 11-17
    Code Fragment That Checks for Warnings After a CONNECT Statement

    Runtime Errors in SQLCODE

    When an SQL statement results in a runtime error, the database server sets SQLCODE (and sqlca.sqlcode) to a negative value. The actual number identifies the particular error. The error message documentation lists the Informix-specific error codes and their corrective actions. To see the error-message documentation, use the finderr or Find Error utility or view Informix Error Messages in Answers OnLine.

    From within your ESQL/C program, you can retrieve error message text that is associated with a negative SQLCODE (sqlca.sqlcode) value with the rgetlmsg() or rgetmsg() library function. See Library Functions for Retrieving Error Messages.

    When the database server encounters a runtime error, it might also set the following other fields in the sqlca structure:

    Errors After a PREPARE Statement

    When the database server returns an error for a PREPARE statement, this error is usually because of a syntax error in the prepared text. When this occurs, the database server returns the following information:

    If you prepare multiple statements with a single PREPARE statement, the database server returns an error status on the first error in the text, even if it encounters several errors.

    Important: The sqlerrd[4] field, which is the offset of the error into the SQL statement, might not always be correct because the ESQL/C preprocessor converts the embedded SQL statements into host-language format. In so doing, the preprocessor might change the relative positions of the elements within the embedded statement.

    For example, consider the following statement, which contains an invalid WHERE clause:

    The preprocessor converts this statement to a string like the following string:

    This string does not have the EXEC SQL keywords. Also, the characters ?, ?, ? have replaced :x, :y, :z (five characters instead of eight). The ESQL/C preprocessor has also dropped a newline character between the left parenthesis (")") and the WHERE keyword. Thus, the offset of error in the SQL statement that the database server sees is different than the offset of the error in the embedded SQL statement.

    The sqlca.sqlerrd[4] field also reports statement-offset values for errors in the EXECUTE IMMEDIATE and DECLARE statements.

    SQLCODE After an EXECUTE Statement

    After an EXECUTE statement, the database server sets SQLCODE to indicate the success of the prepared statement as follows:

    Displaying Error Text

    Your ESQL/C application can use the Informix ERRMESS.HLP file to display text that describes an error and its corrective action. You can call the Windows API WinHelp() with the following WinHelp parameters.

    WinHelp Parameter Data
    HELP_CONTEXT Error number from SQLCODE or sqlca.sqlcode
    HELP_CONTEXTPOPUP Error number from SQLCODE or sqlca.sqlcode
    HELP_KEY Pointer to string that contains error number from SQLCODE or sqlca.sqlcode and is converted to ASCII with sprintf() or wsprintf()
    HELP_PARTIALKEY Pointer to string that contains error number from SQLCODE or sqlca.sqlcode and is converted to ASCII with sprintf() or wsprintf()


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