MDAC 2.5 SDK - OLE DB Providers
OLE DB Provider for ODBC
Known Limitations
The following are known limitations of the OLE DB Provider for ODBC.
General
- The ODBC Provider does not return precision correctly for any numeric data types except DBTYPE_NUMERIC and DBTYPE_DECIMAL. For example, the COLUMNS schema rowset, IColumnsInfo::GetColumnInfo, and IColumnsRowset::GetColumnsRowset return a precision of zero for integer data types.
- The ODBC Desktop Database Driver cannot start a transaction when it has a rowset open. The ODBC Provider returns E_FAIL if ITransactionLocal::StartTransaction is called when any rowset is held open by this driver. This limitation does not necessarily affect other ODBC drivers.
- The ODBC Provider does not quote table names passed through DBIDs; for example, in IOpenRowset. Therefore, when trying to open a table against the ODBC Provider that requires quoting the name (such as when the table name contains extended characters), the consumer must add the quotes to the table name manually or simply execute "Select * from <quoted table name>".
- Query-based updates cannot be used to update BLOB data or other long data.
- The query-based update scheme implemented in the ODBC Provider might not allow for correct repositioning in the rowset after performing an update involving the key columns that were used to generate a keyset cursor–based rowset.
- The ODBC Provider does not support output or input/output parameters as storage objects.
- Using the ODBC Provider, if the underlying ODBC driver does not support SQLDescribeParam and the OLE DB consumer does not specify the type of the parameter, the ODBC Provider will convert Boolean parameter values to "-1" and "0" when the data type of the parameter is string. This is in contrast to the OLE DB Programmer's Reference, which calls for Booleans converted to string data types to appear as the strings "True" or "False." In order to ensure proper conversion against ODBC drivers that do not support describing parameters, the OLE DB consumer should always call SetParameterInfo to specify the types of parameters.
- If DBMEMOWNER_PROVIDEROWNED was set in dwMemOwner in a binding structure and the binding structure binds to a long data column, the ODBC Provider returns DB_E_BADBINDINFO.
- If DBPROP_REMOVEDELETED is set to VARIANT_TRUE on the rowset and a dynamic ODBC cursor is requested and the ODBC Provider cannot provide this type of cursor, any deleted rows scheduled to be removed from the rowset are removed at fetch time. In this situation, it is possible for row-fetching methods (such as GetNextRows or GetRowsAt) to return both S_OK and fewer rows than requested. This irregular behavior is caused by the ODBC Provider requirement to maintain a one-to-one correspondence between OLE DB and ODBC rowsets. This behavior does not signify the DB_S_ENDOFROWSET condition, and the number of rows returned by the fetching method will never be zero if any rows remain (although the number of rows fetched might be smaller than the number requested).
- With non-ODBC 3.x drivers, the ODBC Provider cannot return bookmarks on newly inserted rows. The ODBC Provider marks the status of the bookmark column of the newly inserted row as DBSTATUS_E_UNAVAILABLE. Because ODBC 3.x drivers retrieve bookmarks, updates can be performed on newly inserted rows.
- The ODBC Provider does not allow BLOB data to be set via ISequentialStream on newly inserted rows.
- In a deferred update mode, the ODBC Provider does not support retrieving data set into BLOB columns via ISequentialStream, unless that data has been updated on the provider using IRowsetUpdate::Update.
- When a rowset is created, the OLE DB Provider for ODBC may change the value of DBPROP_CHANGEINSERTEDROWS even though the consumer has explicitly set it. The provider keeps track of its internal state, which may conflict with the consumer's. To reliably find the correct value of this property, the consumer should query the newly created rowset with IRowsetInfo::GetProperties. The specific case in which this provider changes DBPROP_CHANGEINSERTEDROWS to false is when DBPROP_IRowsetUpdate is true and KAGPROP_QUERYBASEDUPDATES is false.
- When performing deferred updates with the DBCOLUMNFLAGS_ISLONG flag, the following two limitations exist:
- If you call SetData for a BLOB column bound as DBTYPE_IUNKNOWN, you cannot retrieve the interface pointer in subsequent calls to GetData. After calling IRowsetUpdate::Update, you can retrieve the value as usual.
- If you call IRowsetUpdate::SetData for a BLOB column not bound in the accessor as DBTYPE_IUNKNOWN, you can retrieve that value as any legal binding other than DBTYPE_IUNKNOWN. After calling IRowsetUpdate::Update, you can retrieve the value in the usual manner.
Microsoft ODBC Driver for Oracle
There are currently no known limitations to using this driver with version 3.0 or later of the OLE DB Provider for ODBC.
Microsoft SQL Server ODBC Driver
- When using a Microsoft SQL Server database as the data store, if the consumer specifies a long column in the WHERE clause of a SELECT statement, the long column cannot contain more than 255 characters.
- Using a Microsoft® SQL Server database as the data store, if the consumer uses SetData to update a BLOB column through an ISequentialStream interface, the length part of the binding must contain the total length of the BLOB data. This differs from other data source objects, which require the length part of the binding to contain only the length of the pointer to the ISequentialStream object.
- Using a Microsoft SQL Server database as the data store, if the consumer opens a forward-only cursor using a query-based update, any method of the IRowsetChange interface may cause a deadlock situation.
The following schema and schema restrictions are supported through the Microsoft SQL Server ODBC driver.
Supported schema |
Supported restrictions |
CATALOGS |
None |
COLUMNS |
All |
TABLES |
All |
PROVIDER_TYPES |
None |
INDEXES |
1, 2, and 5 |
PROCEDURES |
All |
PROCEDURE_PARAMETERS |
All |
COLUMN_PRIVILEGES |
1, 2, 3, and 4 |
FOREIGN_KEYS |
All |
PRIMARY_KEYS |
All |
SCHEMATA |
None |
Microsoft Access ODBC Driver
- When a consumer specifies a value to be inserted or updated in a command and causes a data overflow, but has not called ICommandWithParameters::SetParameterInfo, and the provider cannot determine the column type used by the data source object, the ODBC Provider returns DB_E_DATAOVERFLOW (rather than DB_E_ERRORSOCCURRED with the offending parameter marked with the DBSTATUS_E_DATAOVERFLOW flag). This occurs because the ODBC Provider cannot detect which parameter caused the overflow error.
- In delayed-update mode, consumers who attempt to delete or update rows in a read-only rowset receive the status DBROWSTATUS_DELETED. This differs from the expected status, which is DBROWSTATUS_INTEGRITYVIOLATION.
- The rowset property DBPROP_MAXROWS does not affect the number of rows returned by the Microsoft® Access ODBC driver.
- When run against the Access driver, the ODBC Provider reports output parameter availability as DBPROPVAL_OA_ATROWRELEASE rather than the expected value of DBPROPVAL_OA_NOTSUPPORTED.
The following schema and schema restrictions are supported through the Microsoft Access ODBC driver.
Supported schema |
Supported restrictions |
CATALOGS |
None |
COLUMNS |
All |
TABLES |
All |
PROVIDER_TYPES |
None |
INDEXES |
1, 2, and 5 |
PROCEDURE_PARAMETERS |
All |
PROCEDURE_COLUMNS |
All |
Notifications
- On the first change to a row from SetData, the ODBC Provider does not interleave the SynchAfter and DidEvent notifications. The ordering of OKTODO and ABOUTTODO is correct.
Rowset Properties
- The rowset properties DBPROP_OTHERINSERT and DBPROP_CANHOLDROWS cannot be used together. If you attempt to create a rowset with this combination of properties, the ODBC Provider returns DB_E_ERRORSOCCURRED and returns _NOTSUPPORTED for both properties.
Setting Read-Only Properties to Their Default Values
- The ODBC Provider does not support the OLE DB version 1.1 behavior of allowing consumers to set the value of a read-only property to its default. Although the OLE DB version 1.1 specification clearly indicates that a status of DBPROPSTATUS_OK is returned in "the case where the value of a read-only property was set to its current value," the ODBC Provider returns DBPROPSTATUS_NOTSETTABLE.
Threading
- The ODBC Provider supports the Free Threaded multithreading model; there is no support for Apartment model or mixed threading.
ICommandWithParameters
- The ODBC Provider returns zero for precision and scale when these values do not apply. These values are incorrect and should be ~0 (bitwise NOT 0).
- If the consumer doesn't allocate enough space, a stored procedure that returns a variable-length parameter will not detect the truncation that might have occurred. Instead of returning S_OK and setting the status to DBSTATUS_S_TRUNCATED, the ODBC Provider will return DB_S_ERRORSOCCURRED and set the status to DBSTATUS_S_OK.
IConvertType
- IConvertType::CanConvert returns E_INVALIDARG when a bad dwConvert flag is passed in. This is incorrect; the ODBC Provider should return DB_E_BADCONVERTFLAG.
IDBSchemaRowset
IRowset
- The ODBC Provider does not support execution of RestartPosition when the command text contains parameters; the underlying ODBC driver must, however, support SQLExtendedFetch.
- With IRowset::RestartPosition, the ODBC Provider does not return DB_S_COLUMNSCHANGED when it is supposed to. Instead, it returns E_FAIL.
- If the row on which the rowset is currently positioned is deleted, the consumer must execute IRowset::RestartPosition before retrieving additional row handles with IRowset::GetNextRows.
- If the columns in the underlying data store change and the consumer requests additional rows with IRowset::GetNextRows, the ODBC Provider will fail with the return code E_FAIL.
- If the columns in the underlying data store change, the consumer calls IRowset::RestartPosition, and the reposition operation causes the command to be reexecuted, the ODBC Provider will fail with the return code E_FAIL. The rowset is now invalid, and any method other than ReleaseRows or ReleaseAccessor will fail. If this occurs, the consumer must release all accessors, row handles, and the rowset and must execute the command that created the rowset again.
- When using IRowset::GetData, you can bind to only one long data column based on ISequentialStream; the ODBC Provider can bind to any number of long data columns not based on ISequentialStream.
IRowsetLocate
- When the consumer fetches a row with IRowsetLocate::GetRowsAt, saves the bookmark value corresponding to the row, releases the row, and attempts to fetch the row again using IRowsetLocate::GetRowsAt with the saved bookmark, the second fetch operation might fail. The ODBC Provider returns DB_E_BADBOOKMARK if the underlying ODBC call to SQLExtendedFetch returns S1111 (invalid bookmark value); otherwise, the ODBC Provider returns E_FAIL.
IRowsetResynch
- To enable the ODBC Provider to expose the IRowsetResynch interface, at least one of the following conditions must be met:
- The IRowsetLocate interface is implemented.
- The transaction isolation level is set to SQL_TXN_REPEATABLE_READ.
- The transaction isolation level is set to SQL_TXN_SERIALIZABLE.
- The transaction isolation level is set to SQL_TXN_VERSIONING.
- DBPROP_CANHOLDROWS is set to VARIANT_FALSE, SQLExtendedFetch and SQLSetPos with REFRESH are available from the underlying ODBC driver, and the cursor is not a forward-only cursor.
IRowsetScroll
- IRowsetScroll is supported on ODBC 3.x drivers. If a driver cannot determine the current row position, a value of 1 is returned for the row number in GetApproximatePosition.