![]() |
|
A database cursor is an identifier associated with a group of rows. It is, in a sense, a pointer to the current row in a buffer. You must use a cursor in the following cases:
The following sections summarize how to use cursors in an ESQL/C application. For more information about how to use cursors, see the Informix Guide to SQL: Tutorial.
Statements that return one row of data include a singleton SELECT and an EXECUTE FUNCTION statement whose user-defined function returns only one row of data. Statements that can return more than one row of data include:
For the select or function cursor, you can use a sequential, scroll, hold, or update cursor. Figure 14-5 summarizes the SQL statements that manage a select or function cursor.
Figure 14-5
For more information on any of these statements, see their entries in the Informix Guide to SQL: Syntax. You can change the size of the select or fetch buffer with the Fetch-Buffer-Size feature. For more information, see Sizing the Cursor Buffer.
A select cursor enables you to scan multiple rows of data that a SELECT statement returns. The DECLARE statement associates the SELECT statement with the select cursor. In the DECLARE statement, the SELECT statement can be in either of the following formats:
If the SELECT returns only one row, it is called a singleton SELECT and it does not require a select cursor to execute.
A function cursor enables you to scan multiple rows of data that the user-defined function returns. The following user-defined functions can return more than one row:
You execute a user-defined function with the EXECUTE FUNCTION statement. The DECLARE statement associates the EXECUTE FUNCTION with the function cursor. In the DECLARE statement, the EXECUTE FUNCTION statement can be in either of the following formats:
If the external or SPL function returns only one row, it does not require a function cursor to execute.
When you execute the INSERT statement, the statement sends one row of data to the database server. When an INSERT statement sends more than one row, define an insert cursor with the DECLARE statement. An insert cursor enables you to buffer multiple rows of data for insertion at one time. The DECLARE statement associates the INSERT statement with the insert cursor. In the DECLARE statement, the INSERT statement can be in either of the following formats:
If you use an insert cursor it can be much more efficient than if you insert rows one at a time, because the application process does not need to send new rows to the database as often. You can use a sequential or hold cursor for the insert cursor. Figure 14-6 summarizes the SQL statements that manage an insert cursor.
Figure 14-6
For more information on any of these statements, see their entries in the Informix Guide to SQL: Syntax. You can change the size of the insert buffer with the Fetch-Buffer-Size feature. For more information, see Sizing the Cursor Buffer.
In an ESQL/C program, you can specify a cursor name with any of the following items:
INFORMIX-ESQL/C supports the following features that allow you to minimize network traffic when an ESQL/C application fetches rows from a database server:
The cursor buffer is the buffer that an ESQL/C application uses to hold the data (except simple large-object data) in a cursor. ESQL/C has the following uses for the cursor buffer:
With a fetch buffer, the client application performs the following tasks:
For subsequent FETCH statements, the application checks whether more rows exist in the fetch buffer. If they do, it takes the next row out of the fetch buffer. If no more rows are in the fetch buffer, the application requests more rows from the database server, sending the fetch-buffer size.
The client application uses an insert buffer to perform the following tasks:
The application continues this procedure until no more rows are put into the insert buffer. It sends the contents of the insert buffer to the database server when:
The client application sends the prepared statement that is associated with the cursor to the database server and requests DESCRIBE information about the statement. If the cursor has an associated prepared statement, ESQL/C makes this request when the PREPARE statement executes. If the cursor does not have an associated statement, ESQL/C makes the request when the DECLARE statement executes.
When it receives this request, the database server sends the DESCRIBE information about each column in the projection list to the application. With this information, ESQL/C can determine the size of a row of data. By default, ESQL/C sizes this cursor buffer to hold one row of data. It uses the following algorithm to determine the default size of the cursor buffer:
Once it has the buffer size, ESQL/C allocates the cursor buffer.
Changing Size of Cursor BufferAn ESQL/C application might want to increase the size of the cursor buffer to increase the number of rows that can be passed at one time between the client application and the database server. When you increase the number of rows that can be passed, you reduce the number of round-trip message requests that need to be sent between the client application and the database server. The bigger the cursor buffer, the more data that can be sent in one round trip.
To increase the size of the cursor buffer, you can set either of the following variables in the client environment:
Tip: Contrary to what the names might imply, the FET_BUF_SIZE environment variable and the FetBufSize global ESQL/C variable do not change the size of only the fetch buffer. They change the size of the cursor buffer, which is used for both the fetch buffer and the insert buffer.
In a client-server environment, you must set the cursor buffer size on the client side of the application because this buffer resides in the application process. Specify the size of the cursor buffer in bytes, up to the maximum size of a small integer (short data type) on your system. For most 32-bit platforms, this maximum is 32,767 bytes. If you specify a buffer size that is less than the default size or greater than the system maximum, the new size is ignored. If you do not specify a buffer size, the database server uses the default size.
Important: Informix extends ANSI-standard syntax to set the size of the cursor buffer.
If you increase the size of the cursor buffer, you reduce the overhead of refilling the buffer. The database server can buffer more data before it sends it to the application. A larger fetch buffer can enhance performance when you fetch a large number of rows or when a single row is large. The greater the size of the fetch buffer, the fewer number of times the application needs to wait while the database server retrieves a large number of rows or a few large rows. However, when you fetch only a few rows (unless the row is very large), the performance gain is not as apparent.
When an ESQL/C application uses a cursor, it usually sends a FREE statement to the database server to deallocate memory assigned to a select cursor once it no longer needs that cursor. Execution of this statement involves a round trip of message requests between the application and the database server. The Automatic-FREE feature (AUTOFREE) reduces the number of round trips by one.
When the AUTOFREE feature is enabled, ESQL/C saves a round trip of message requests because it does not need to execute the FREE statement. When the database server closes a select cursor, it automatically frees the memory that it has allocated for it. Suppose you enable the AUTOFREE feature for the following select cursor:
When the database server closes the sel_curs cursor, it automatically performs the equivalent of the following FREE statement:
If the cursor had an associated prepared statement, the database server also frees memory allocated to the prepared statement. Suppose you enable the AUTOFREE feature for the following select cursor:
When the database server closes the sel_curs2 cursor, it automatically performs the equivalent of the following FREE statements:
You must enable the AUTOFREE feature before you open or reopen the cursor.
Enabling the AUTOFREE FeatureYou can enable the AUTOFREE feature for an ESQL/C application in either of the following ways:
Warning: Be careful when you enable the AUTOFREE feature in legacy ESQL/C applications. If a legacy application uses the same cursor twice, it generates an error when it tries to open the cursor for the second time. When the AUTOFREE feature is enabled, the database server automatically frees the cursor when it closes it. Therefore, the cursor does not exist when the legacy application attempts to open it a second time, even though the application does not explicitly execute the FREE statement.
For more information on the syntax and use of the SET AUTOFREE statement, see Using the SET AUTOFREE Statement. For more information on the IFX_AUTOFREE environment variable, see the Informix Guide to SQL: Reference.
Using the SET AUTOFREE StatementYou can use the SQL statement, SET AUTOFREE, to enable and disable the AUTOFREE feature. The SET AUTOFREE statement allows you to take the following actions in an ESQL/C program:
The SET AUTOFREE statement overrides any value of the IFX_AUTOFREE environment variable.
The following code fragment uses the FOR clause of the SET AUTOFREE statement to enable the AUTOFREE feature for the curs1 cursor only. After the database server executes the CLOSE statement for curs1, it automatically frees the cursor and the prepared statement. The curs2 cursor and its prepared statement are not automatically freed.
When you use the AUTOFREE feature, make sure you do not cause a prepared statement to become detached. This situation can occur if you declare more than one cursor on the same prepared statement. A prepared statement is associated or attached to the first cursor that specifies it in a DECLARE statement. If the AUTOFREE feature is enabled for this cursor, then the database server frees the cursor and its associated prepared statement when it executes the CLOSE statement on the cursor.
A prepared statement becomes detached when either of the following events occur:
This second condition can occur if the AUTOFREE feature is not enabled for a cursor and you free only the cursor, not the prepared statement. The prepared statement becomes detached. To reattach the prepared statement, declare a new cursor for the prepared statement. Once a prepared statement was freed, it cannot be used to declare any new cursor.
The following code fragment declares the following cursors on the slct1 prepared statement:
The following code fragment shows how a detached prepared statement can occur:
For more information on the ../sqls/intro.htmltax and use of the SET AUTOFREE statement, see the Informix Guide to SQL: Syntax.
When an ESQL/C application uses a PREPARE/DECLARE/OPEN statement block to execute a cursor, each statement involves a round trip of message requests between the application and the database server. The Deferred-PREPARE feature reduces the number of round trips by one. When the Deferred-PREPARE feature is enabled, ESQL/C saves a round trip of message requests because it does not need to send a separate command to execute the PREPARE statement. Instead, the database server automatically executes the PREPARE statement when it receives the OPEN statement.
Suppose you enable the Deferred-PREPARE feature for the following select cursor:
The ESQL/C application does not send the PREPARE statement to the database server when it encounters the PREPARE before the DECLARE statement. Instead, it sends the PREPARE and the OPEN to the database server together when it executes the OPEN statement.
You can use the Deferred-PREPARE feature in ESQL/C applications that contain dynamic SQL statements that use statement blocks of PREPARE, DECLARE, and OPEN to execute the following statements:
For example, the Deferred-PREPARE feature reduces network round trips for the following select cursor:
When you enable the deferred-PREPARE feature, the client application does not send PREPARE statements to the database server when it encounters them. The database server receives a description of the prepared statement when it executes the OPEN statement.
The database server generates an error if you execute a DESCRIBE statement on a prepared statement before the first OPEN of the cursor. The error occurs because the database server has not executed the PREPARE statement that the DESCRIBE statement specifies. When the deferred-PREPARE feature is enabled, you must execute the DESCRIBE statement after the first OPEN of a cursor.
Important: The deferred-PREPARE feature eliminates execution of the PREPARE statement as a separate step. Therefore, the application does not receive any error conditions that might exist in the prepared statement until after the initial OPEN.
For more information, see Using the SETDEFERRED_PREPARE Statement.
Enabling the Deferred-PREPARE FeatureYou can enable the Deferred-PREPARE feature for an ESQL/C application in either of the following ways:
For more information on the syntax and use of the SET DEFERRED PREPARE statement, see "Using the SETDEFERRED_PREPARE Statement." For more information on the IFX_DEFERRED_PREPARE environment variable, see the Informix Guide to SQL: Reference.
Using the SETDEFERRED_PREPARE StatementIn an ESQL/C application you can use the SQL statement, SET DEFERRED_PREPARE, to enable and disable the Deferred-PREPARE feature. The SET DEFERRED_PREPARE statement allows you to take the following actions in an ESQL/C program:
The SET DEFERRED_PREPARE statement overrides any value of the IFX_DEFERRED_PREPARE environment variable.
The following code fragment shows how to enable the Deferred-PREPARE feature for the ins_curs insert cursor:
To execute a DESCRIBE statement on a prepared statement, you must execute the DESCRIBE after the initial OPEN statement for the cursor. In the following code fragment the first DESCRIBE statement fails because it executes before the first OPEN statement on the cursor. The second DESCRIBE statement succeeds because it follows an OPEN statement.