Share via


Deferred Columns

For a deferred column, the provider is not required to retrieve data from the data store until IRowset::GetData is called for that column. If the column contains a COM object, the provider need not retrieve data until a method used to access that object is called. It is provider-specific when the data in a deferred column is actually retrieved. For example, it might be retrieved when the command is executed, when the row handle is fetched, lazily in the background, or when IRowset::GetData or a method on another interface is called for the column. If a column is deferred, the DBCOLUMNFLAGS_MAYDEFER enumerated type flag returned by IColumnsInfo::GetColumnInfo is set for the column.

Whether the provider caches the data for a deferred column depends on the setting of the DBCOLUMNFLAGS_CACHEDEFERRED property returned by IColumnsInfo::GetColumnInfo. If this property is set to VARIANT_TRUE, the column value is cached when first read. The cached value is returned whenever the column is read. It can be changed by calling IRowsetChange::SetData or IRowsetRefresh::RefreshVisibleData. In that case, it is released only when the row handle is released. If the DBCOLUMNFLAGS_CACHEDEFERRED flag is not set, multiple calls to IRowset::GetData can return different values. Otherwise, such calls are not guaranteed to reflect a change to the underlying column unless IRowsetRefresh::RefreshVisibleData has been called.

Whether or not a column is deferred by default is provider-specific and may vary depending on the column. To retrieve a column as deferred or cache deferred, the consumer sets the DBPROP_DEFERRED or DBPROP_CACHEDEFERRED column property on the column, respectively. To determine whether or not a column is deferred, the consumer checks the DBCOLUMNFLAGS_CACHEDEFERRED and DBCOLUMNFLAGS_MAYDEFER bits in the dwFlags element of the DBCOLUMNINFO structure returned by IColumnsInfo::GetColumnInfo or the DBCOLUMN_FLAGS column returned in IColumnsRowset::GetColumnsRowset.

Note

The value of DBPROP_DEFERRED is automatically set to VARIANT_TRUE if DBPROP_CACHEDEFERRED is set to VARIANT_TRUE.

Using deferred columns increases isolation risk for consumers because deferred data might be read at a different time than nondeferred data. If the consumer is not using repeatable-read transaction isolation or a higher isolation level, it might encounter discrepancies between the original and the deferred access to a row. In particular, the consumer might find that the column is missing because the row has been deleted, or the column might not match the rest of the row. However, under some circumstances, a row version column in conjunction with both original and deferred access can be used to warn a consumer about a situation where a concurrent error has occurred. A consumer can determine whether a column contains a row version by examining the DBCOLUMNFLAGS_ISROWVER flag in IColumnsInfo::GetColumnInfo.