Positioning the cursor and fetching records

<< Click to Display Table of Contents >>

Navigation:  Application development > Accessing and updating tables >

Positioning the cursor and fetching records

Previous pageReturn to chapter overviewNext page

After the record buffer has been prepared, the application can use the record buffer to fetch records from the table.

To fetch records, the application must position the cursor on the record that it wants to fetch. Some BDE functions serve only to position the cursor. Calls to these functions can be followed by a call to a function that fetches the record into the record buffer. Other BDE functions can simultaneously position the cursor and fetch a record into the record buffer.

Positioning the cursor on a crack

Some BDE functions position the cursor before a record, at the beginning of the file or result set, or at the end of the file. When the cursor is positioned at one of these locations, rather than on a record, the cursor is said to be positioned on a crack. The following calls position the cursor on a crack:

DbiSetToBegin positions the cursor to the beginning of the file (just before the first record). When the cursor is opened, it is at this position.

DbiSetToEnd positions the cursor to the end of the file (just after the last record).

DbiSetToKey positions the cursor just prior to the record of the specified key value.

Positioning the cursor on a crack can simplify programming. For example, calling DbiSetToBegin positions the cursor on the crack before the first record in the table. Then, you can set up a loop to process all the records in the table with DbiGetNextRecord. (If the cursor had been positioned on the first record in the table to start with, instead of before the first record, the DbiGetNextRecord loop would have skipped the first record.)

Positioning the cursor on a record and fetching a record

Some BDE functions position the cursor directly on a record. If a record buffer is supplied, these functions can also be used to fetch the record for processing by the application. Most of these calls can optionally lock the record. The record remains locked until it is released explicitly, or the session is closed. For more information about locks, see Locking

DbiGetRecord
This function fetches the current record, and returns an error if the cursor is positioned on a crack.

DbiGetNextRecord
This function positions the cursor on the next record after the current position of the cursor, and also fetches that record.

DbiGetPriorRecord
This function positions the cursor on the record before the current position of the cursor, and also fetches that record.

DbiGetRelativeRecord
This function positions the cursor on the record whose position is specified as an offset (either a positive or a negative number) from the current position of the cursor, and also fetches that record.

DbiGetRecordForKey
This function positions the cursor on the record whose key matches the specified key, and also fetches that record.

Example

The following example shows how to position the cursor to the beginning of file and step through the table:

 // Position the cursor at the BOF crack

    DbiSetToBegin(hCursor);

    // Step through the table. Read the record each time.

    while (DbiGetNextRecord(hCursor, dbiNOLOCK, pRecBuf, NULL)

           == DBIERR_NONE)

    {

      ...

    }

Repositioning the cursor with bookmarks

Bookmarks provide a convenient way to save the position of the cursor, so that it can be repositioned to that same place later. The bookmark is written to a client-supplied buffer which is allocated by the client.

Note:The size of the bookmark buffer may change after a call to DbiSwitchToIndex.

DbiGetBookmark
This function saves the current position in the supplied bookmark.

DbiSetToBookmark
This function repositions the cursor to a previously saved bookmark position.

Fetching multiple records

The application can fetch multiple records with one call by setting up a buffer large enough to hold the records and calling DbiReadBlock. The specified number of records are fetched beginning with the next record after the current cursor position. This function is equivalent to setting up a loop that makes multiple calls to DbiGetNextRecord.

Retrieving limited record sets

Several BDE functions enable you to force the cursor to return only a limited set of records or fields to the application; that is, the application sees only those records in the table that meet a predefined set of conditions.

Note:Queries provide another way of returning a limited record set.

Using ranges

Use DbiSetRange to force the cursor to return to the application only those records whose keys fall within the defined range. This function can be called only if the cursor has a current active index. (See DbiOpenTable or DbiSwitchToIndex) Both inclusive and exclusive ranges can be specified. Subsequent BDE calls treat the set of records within the range as the complete table. For example, DbiSetToBegin positions the cursor on the crack before the first record in the range, rather than on the first record in the table.

This function is commonly used to find a set of records between two key values by setting both the upper range limit and the lower range limit. Open-ended ranges can be specified, from the beginning of the file to a specified key, or from a specified key to the end of the file.

Creating field maps

Use DbiSetFieldMap to force the cursor to return fields in a different order from their order in the table, or to drop fields from view. To set up a field map, the application developer builds an array of field descriptors, including only those fields that are to be made visible by the cursor, and in the order that they are to be returned. Only the fields named in the array are made visible.

Note:Creating field maps can change the size of the record buffer.

Using filters

An active filter forces the cursor to return a limited record set consisting of only those records that meet the filter condition. Records that do not meet the filter condition are skipped, and even though they remain in the table, the records are not visible through the cursor. Deactivating the filter brings those records back into view.

A filter condition is defined as an expression returning TRUE or FALSE. When the filter is activated, the filter expression is applied to each record in the table. Only those records that return TRUE are visible to the application. Multiple filters can be defined for one table.

To define a filter, the application calls DbiAddFilter, passing it an existing cursor handle and a pointer to a CANExpr structure that contains the expression. The structure is passed in a flat tree format. (For a detailed explanation and an example of how to use filters, see Filtering records.)

The CANExpr structure can include comparison operators, AND, OR, and NOT, and tests for blank fields. Different drivers support different types of expressions, but all drivers support the basic combination of <field> <compare operator> <constant>; for example, "field1 = "CA" and field2 < 30" is supported by all drivers.

When DbiAddFilter completes, it returns a filter handle to the application.

After the filter condition has been defined, it must be activated with DbiActivateFilter in order to take effect. Multiple filters can be activated. Filters can be switched on and off when needed (using DbiActivateFilter and DbiDeactivateFilter). Filters are automatically dropped when the cursor is closed, and can be explicitly dropped with DbiDropFilter. If more than one filter is active, records that fail to meet any active filter condition are filtered out.

Advantages of using filters are that the BDE filtering mechanism is extremely fast, and filters are implemented efficiently by the drivers.

Note:While queries provide a more general way of restricting the result set than filters, filters provide more dynamic control than queries.