PDA

View Full Version : Problem with Foxpro dB, ADO and Visual C++


BeeDub
03-09-08, 22:29
Has anyone had success using ADO and C++ on a Visual Foxpro database?

I am having a problem with a C++ app I am writing using ADO to work with Visual Foxpro databases.

I can open and read the tables, but any attempt to Update the db ends with error 80040e21. I am sure that the datatypes are correct and no strings are too long. Even changing a simple integer causes the error on Update.

I have tried it with and without the Edit command, with and without primary keys and different permissions.

Below is some example code, also see attached '_tempinfo.zip'.

Please help.

Thanks, BeeDub


// Provider: Visual FoxPro
// Database: TestDb.dbc
// Table: TestTbl.dbf (with primary key index on nID field)
// Problem: Can read the table but cannot write to it
// UPDATE() BREAKS WITH 80040e21 ERROR
//----------------------------------------------------------


#import "C:\Program Files\Common Files\System\ADO\msadox.dll" rename_namespace("NSADOX") rename("EOF", "adoxEOF")
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename_namespace("ADOCG") rename("EOF", "EndOfFile")
using namespace ADOCG;


try
{
// Open Database
::CoInitialize(NULL);
_ConnectionPtr m_pConnection=NULL;
m_pConnection.CreateInstance(__uuidof(Connection)) ;
CString csConnection = _T("Provider=vfpoledb.1;Data Source=TempDb.dbc");
HRESULT hr = m_pConnection->Open(_bstr_t(csConnection), _T(""), _T(""), NULL);

// Open Recordset
_RecordsetPtr m_pRecordset=NULL;
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_pRecordset->CursorLocation = ADOCG::adUseClient;
m_pRecordset->Open((LPCSTR)"TempTbl.dbf", _variant_t((IDispatch*)m_pConnection, TRUE),
adOpenKeyset, adLockOptimistic, adCmdTable);

// make changes to the Recordset
LPCTSTR lpFieldName = "cName";
CString csValue = "";
_variant_t vtFld;
vtFld.vt = VT_BSTR;
vtFld.bstrVal = csValue.AllocSysString();

// GetFieldValue (irrelevant, but successful)
vtFld = m_pRecordset->Fields->GetItem(lpFieldName)->Value;
// SetFieldValue
csValue = "testing 1-2-3";
vtFld.bstrVal = csValue.AllocSysString();
m_pRecordset->Fields->GetItem(lpFieldName)->Value = vtFld;

// update the Recordset
//UPDATE() BREAKS WITH 80040e21 ERROR
if (m_pRecordset->Update() != S_OK)
m_pRecordset->CancelUpdate();

}
catch(_com_error &e)
{
CString csError;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
csError.Format( "CADORecordset Error\n\tCode = %08lx\n\tCode meaning = %s\n\tSource = %s\n\tDescription = %s\n",
e.Error(), e.ErrorMessage(), (LPCSTR)bstrSource, (LPCSTR)bstrDescription );
AfxMessageBox(csError);:confused: