Types of Cursors

Cursors can be either updateable or non-updateable. If you only need to display information and not diddle with it, the non-updateable is the fastest. The provider simply passes you the data and forgets about it! There is no need to keep tabs on the data to see if it has been changed. Therefore, this is the fastest cursor to use.

Scrollable cursors, which can be updateable or non-updateable, permit you to move (scroll) back and forth in the recordset. If you only need to blast out some data to a grid or HTML page, a non-scrollable cursor will give a performance boost. This is because there is no need to track where you are in the recordset.

Keyset-Driven cursors take note of a key you may have in your database. Under normal circumstances, when you request records from a data source, you get the entire package. However, when a Keyset cursor is selected, only the keys are returned, giving a performance boost. Then, when you scroll through the recordset, the data for the keys is retrieved. However, when you first invoke the cursor, both keys and data are returned so you can see something in your bound control. When you scroll, and the data is not in the current batch of data, the Keyset fetches the next block. This way it only has to manage small keys rather than large chunks of data.

Dynamic and Static cursors determine what data is available in the cursor at any point in time.  As the name implies, Static cursors only contain data that was placed in the cursor when it was created. However, with a Dynamic cursor, any new records that are added to the recordset are available. It's like a living cursor.

We can use our old friend the Object Browser to see the cursor types available to us:

With ADO, we have the choice of four types of cursors. We can simply use constants to tell the recordset which to use:

Cursor type Constant
Static cursor. This is the one to use for generating reports or finding data. Additions, changes, or deletions by other users are not visible. adOpenStatic
Forward-only cursor. This is the default. It is identical to the Static except that you can only scroll forward. The fastest cursor this side of the Pecos Mountains. adOpenForwardOnly
Dynamic cursor. Additions and deletions by others are visible. All movement is supported. But some providers don't support this cursor type. adOpenDynamic
Keyset-driven cursor. This is similar to a Dynamic cursor except you can't see records others add. If another user deletes a record, it is inaccessible from your recordset. adOpenKeyset

We can also tell the recordset how to lock our data while it's being manipulated via the cursor:

Lock Type Description
AdLockReadOnly Default. Read-only: you cannot alter the data.
AdLockPessimistic Pessimistic locking, record by record—the provider does what is necessary to ensure successful editing of the records, usually by locking records at the data source immediately upon editing.
AdLockOptimistic Optimistic locking, record by record—the provider uses optimistic locking, locking records only when you call the Update method.
AdLockBatchOptimistic Optimistic batch updates—required for batch update mode as opposed to immediate update mode.

Opening ADO Recordsets – Syntax

The syntax for opening an ADO recordset is like this:

adoRecordset.Open Source, ActiveConnection, CursorType, LockType, Options

The Source argument is Optional. This is a valid command object variable name, or it might be an SQL statement, a table name, or a stored procedure call.

The ActiveConnection is also optional. This is either a valid Connection object variable name, or a String that contains our ConnectionString.

The CursorType is also Optional. This is simply one of the cursor constants that tells the provider the type of cursor to use when opening the Recordset.

ConnectionString Options

There are several other options that we can provide the recordset as well. You may recall that when we build the connect string in our ADO data control, these options were provided in a drop down box. They may have looked a bit cryptic back then, but now we can see what they mean:

Description Constant
The provider should take the source as a text description of a command, such as a SQL statement adCmdText
ADO should generate an SQL statement to fetch all rows from the table in Source adCmdTable
The provider should return all of the rows from the table named in Source. adCmdTableDirect
The provider should treat the Source as a stored procedure adCmdStoredProc
The type of command in Source is unknown. You should not use this! It is the slowest of all cursors. AdCmdUnknown
A saved recordset should be restored from the file names in Source adCommandFile
Source should be executed asynchronously adFetchAsync
After the initial quantity of records specified in CacheSize is fetched, any remaining rows should be fetched asynchronously adFetchAsync

When might you use some of these options? Well, a good illustration would be when using a transaction.

© 1998 by Wrox Press. All rights reserved.