OleDbOrc.exe: Using the OLE DB Cursor Engine Service to Provide Updatability for OLE DB Providers

ID: Q223333


The information in this article applies to:


SUMMARY

Some OLE DB providers, such as Microsoft's Oracle OLE DB Provider, do not support updating via IRowsetChange, although they do support updating via SQL UPDATE statements. In this case, the OLE DB Cursor Engine service can be used to allow the provider to be updatable via IRowsetChange.

OleDbOrc.exe is a self-extracting executable containing two files, SDKServiceSample.cpp and VCServiceSample.cpp, that demonstrate how to invoke the OLE DB services when using the Oracle OLE DB Provider so that you can get the IRowsetChange interface and perform updates, insertions, or deletions.

SDKServiceSample.cpp uses OLE DB SDK function calls while VCServiceSample.cpp uses the OLE DB Consumer template C++ classes.

To build the samples, bring the .cpp file into the Visual C++ development environment and choose Build. The program will ask whether you want a default workspace created, choose Yes.


MORE INFORMATION

The following file is available for download from the Microsoft Software Library:

OleDbOrc.exe
Release Date: May-27-1999

For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
Q119591 How to Obtain Microsoft Support Files from Online Services


Filename Size
SDKServiceSample.cpp 8KB
VCServiceSample.cpp 3KB

Invoking OLE DB Services, Such As the OLE DB Cursor Engine

To use such OLE DB services as the Cursor Engine, refer to the Data Access SDK 2.1 documentation. Specifically, look up "OLE DB Services." To use OLE DB services, you must use IDataInitialize or IDBPromptInitialize. Following is the sample code from the OleDbOrc sample:

Sample Code


// The Init Prompt
InitProperties[0].dwPropertyID = DBPROP_INIT_PROMPT;
InitProperties[0].vValue.vt = VT_I2;
InitProperties[0].vValue.iVal = DBPROMPT_NOPROMPT; 	
// Data source string.
InitProperties[1].dwPropertyID = DBPROP_INIT_DATASOURCE;	
InitProperties[1].colid = DB_NULLID;
InitProperties[1].vValue.vt = VT_BSTR;
InitProperties[1].vValue.bstrVal =  SysAllocString(OLESTR("dseoracle"));
// User ID.
InitProperties[2].dwPropertyID = DBPROP_AUTH_USERID;
InitProperties[2].vValue.vt = VT_BSTR;
InitProperties[2].vValue.bstrVal = SysAllocString(OLESTR("demo"));
// Password.
InitProperties[3].dwPropertyID = DBPROP_AUTH_PASSWORD;
InitProperties[3].vValue.vt = VT_BSTR;
InitProperties[3].vValue.bstrVal = SysAllocString(OLESTR("demo"));
// Load the service components.
InitProperties[4].dwPropertyID = DBPROP_INIT_OLEDBSERVICES;
InitProperties[4].vValue.vt = VT_I4;
InitProperties[4].vValue.lVal = DBPROPVAL_OS_ENABLEALL;

rgInitPropSet.guidPropertySet = DBPROPSET_DBINIT; // The property set.
rgInitPropSet.cProperties = 5;  // # of properties being set.
rgInitPropSet.rgProperties = InitProperties; // Array of DBPROP structures.

...

if (FAILED(hr = CoCreateInstance(CLSID_MSDAINITIALIZE, NULL, 
                CLSCTX_INPROC_SERVER, IID_IDataInitialize, 
                (void**)&pDataInit)))
   RETURN(hr)
// Creating the IDBInitialize.
if(FAILED(hr = CLSIDFromProgID(wszProvider, &clsid)))
   RETURN(hr)
if(FAILED(hr = pDataInit->CreateDBInstance(clsid, NULL, 
          CLSCTX_INPROC_SERVER, NULL, IID_IDBInitialize, (IUnknown**)
          &pDataSourceIDBInitialize)))
   RETURN(hr)

// Setting the initialization properties.
if(FAILED(hr = pDataSourceIDBInitialize->QueryInterface(IID_IDBProperties, 
               (void**)&pProperties)))
   RETURN(hr)
if(FAILED(hr = pProperties->SetProperties(1,&rgInitPropSet)))
   RETURN(hr)
if (FAILED(hr = pDataSourceIDBInitialize->Initialize( )))
   RETURN(hr) 

Notice the setting of DBPROP_INIT_OLEDBSERVICES. If you are using the Visual C++ 6.0 ATL OLE DB Consumer templates, you can use the OpenWithServiceComponents() function. For example:

CDataSource ds;
ds.OpenWithServiceComponents("MSDAORA", propset); 
Once the datasource is opened using the service components, any rowsets created with ICommand::Execute() use the cursor engine if the provider doesn't provide the necessary functionality (scrolling and updating for example).

NOTE: If the OLE DB consumer asks for ICommandText and calls Execute, the services will not be used. You must use QueryInterface() for ICommand and then query for ICommandText from that pointer.

For additional information about, please see the following article in the Microsoft Knowledge Base:
Q223417 Bug: Cursor Services Not Used: Execute Called from ICommandText

Additional query words:


Keywords          : kbfile kbDatabase kbOLEDB kbOracle kbConsumer kbVS600sp2 kbGrpVCDB kbGrpMDAC kbMDAC200 kbMDAC150 
Version           : WINDOWS:1.5,2.0,6.0 SP2
Platform          : WINDOWS 
Issue type        : kbhowto 

Last Reviewed: June 2, 1999