Using Accessors

Accessors are created with IAccessor::CreateAccessor, reference-counted with IAccessor::AddRefAccessor, and released with IAccessor::ReleaseAccessor. They can be created and released at any time. An accessor can be a parameter accessor (used for accessing parameter data), a row accessor (used for accessing rowset data), or both. Parameter accessors must be created and used on the command. Row accessors can be created on the command or the rowset and must be used on the rowset. Row accessors created after a row is fetched can still be used against that row.

When ICommand::Execute creates a rowset, the rowset inherits all row accessors that have been created on that command. To the consumer, it appears as if each accessor has been copied from the command to the rowset: the bindings, flags, and handle of each accessor are the same on both the rowset and the command. Once the rowset is opened, it gets its own independent copy of the accessors. Calling IAccessor on the command object has no effect on the accessors available on any existing rowsets, and calling IAccessor on the rowset has no effect on the accessors available on any existing commands.

For example, suppose the text command that creates a rowset contains parameters. The consumer might create multiple rowsets by repeatedly executing this text command with different parameters. Because the rowsets are created from the same text command, all can use the same row accessors. It is therefore more efficient to create these accessors once on the command, rather than creating them separately on each rowset. To create a row accessor on a command, the consumer must know the column ordinals. For a text command such as SELECT * FROM MyTable, there is no way to know the order of the result columns. In such a case, the consumer must define the row accessor on the rowset or modify the text command to list the columns. For commands that generate a hierarchy of rowsets, only the first (root) rowset inherits the row accessors from the command.

Consumers can create and use more than one accessor on a single row. Thus, the consumer can get or set multiple copies of the same data. For example, suppose a rowset contains employee data including a picture of the employee. The consumer might create two accessors: one for all of the columns except the picture column and another for the picture column. The consumer might then pass the handle of the first accessor to IRowset::GetData to get all of the data except the picture. When the user requests the picture, the consumer would then pass the handle to the second accessor to GetData to get the picture.

Row accessors can be optimized. How this is done is provider specific. In general, it is faster to use an optimized accessor than a nonoptimized accessor. For example, the provider might structure its internal row buffers to match the types used in the accessor. Optimized row accessors must be created before any rows are fetched.

Flagging accessors as optimized affects only providers that support optimized accessors. In general, providers are not required to recognize optimized accessors, nor are they required to enforce any of the restrictions associated with optimized accessors.

However, clients written to consume data from general OLE DB providers should never include the same column in more than one optimized accessor, and for all bindings to a particular column, should use a data type coercible from the type specified in any optimized accessor for that column.