Creating a Disconnected Recordset in C++ For VB 

Environment: Visual C++ 6.0 and VB 6.0, ADO 1.5 

This article assumes that you are familiar with ADO, Visual C++ and ATL.

This article shows how to create a Visual C++ COM object that creates a disconnected ADO Recordset. With a disconnected ADO recordset, your ATL COM object can connect to the database, create the Recordset, and disconnect without having to keep a connection open, while allowing the client to read the data in the Recordset. This works great with MTS where database connection pooling requires this functionality.

Resources: HOWTO: Getting ADO Disconnected Recordsets in VBA/C++/Java 

SAMPLE: ATL2ADO.exe Returns Disconnected ADO Recordset

In your project make sure you import dll to create your ADO classes.

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF") implementation_only

Next create a method with an [out, retval] property of type _Recordset **

[id(1), helpstring("method GetADORecordset")] HRESULT GetADORecordset( [out, retval] _Recordset **ppRecordset);

Your source code should look something like this:

STDMETHODIMP CReturnADO::GetADORecordset(_Recordset **ppRecordset)

{

_ConnectionPtr pConnection;

_RecordsetPtr pRecordset;

try

{

pConnection.CreateInstance(__uuidof(Connection));

pConnection->CursorLocation = adUseClient; // Important for disconnected sets

pConnection->Open("DSN=SQLSource","loginnmae","password",-1);

pRecordset.CreateInstance(__uuidof(Recordset));

pRecordset->CursorLocation = adUseClient; // Important for disconnected sets

pRecordset->PutRefActiveConnection(pConnection.GetInterfacePtr()); // Associate the connection to this recordset

pRecordset->Open("SELECT DISTINCT name FROM TBLWHATEVER WHERE name IS NOT NULL",vtMissing,

adOpenForwardOnly, adLockReadOnly,

adCmdText);

        pRecordset->PutRefActiveConnection(NULL); // Disassociate the connection from the recordset.

if(pConnection->GetState() == adStateOpen)

pConnection->Close();

pConnection = NULL;

*ppRecordset = pRecordset.Detach();

}

catch(_com_error *e)

{

return AtlReportError(CLSID_ReturnADO,e->ErrorMessage(),IID_IReturnADO,E_FAIL);

}

catch(...)

{

return AtlReportError(CLSID_ReturnADO,"Unknown Error.",IID_IReturnADO,E_FAIL);

}

return S_OK;

}

Now your interface descriptions and CLSID's will be different, but go ahead and use this code to build your own version. Your VB code might look something like this:

    Dim adoset As ADODB.Recordset

    Dim engine As New TESTRETURNADOLib.ReturnADO

    

    Set adoset = engine.GetADORecordset

    While Not adoset.EOF

        List1.AddItem adoset.Fields(0)

        adoset.MoveNext

    Wend

    

    Set adoset = Nothing

Date Posted: May 20, 1999