I see your using MFC but my ATL code should still help you STDMETHODIMP CDoc_Session::SQLSearch(BSTR bstrSQL, Recordset ** ppRecSet) { HRESULT hr; try { _bstr_t bstrSearch(bstrSQL); if(bstrSearch.length()>0) { _RecordsetPtr piRS; hr = piRS.CreateInstance(__uuidof(Recordset)); if(FAILED(hr)) return hr; piRS->CursorLocation = adUseClient; piRS->Open(bstrSearch, m_piConn->ConnectionString, adOpenForwardOnly,adLockReadOnly,adCmdUnknown); if(VARIANT_FALSE == piRS->GetADOEOF()) return piRS->QueryInterface(__uuidof(_Recordset), reinterpret_cast(ppRecSet)); else return E_FAIL; } else return E_FAIL; } catch (_com_error e) { ::MessageBox(NULL, e.Description(), "DNS", MB_OK); return e.Error(); } catch (...) { return E_FAIL; } return S_OK; } 1. You need to change your variant return value to a Recordset ** ppRecSet. You will need to do a #importlib of the msado15.dll in the library section of your .idl file. This is so the midl compiler will be able to marshell the Recordset type. 2. Next you need to make sure returning Recordset->CursorLocation=adUseClient; 3. Finally you need do a QueryInterface on the local Recordset so that can intialize the returing record set. If you need more help on this I think I might be able to find some old MFC code that does this same thing. Good Luck