Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ODBC MFC CRecordset error at runtime

Status
Not open for further replies.

rdg2cig

Programmer
Sep 16, 1999
22
US
I am trying to add access to a database (currently extracted into MS Access 97 during development) into an existing MFC application that did not originally include database support. I have registered the database as &quot;RAMS&quot; through the ODBC utility on the Windows Control Pnnel. I used ClassWizard to extend the CRecordset class as CCuHdrSet and configured within the wizard to my RAMS database and one table within it CuHdr. I included <afxdb.h> in the CuHdrSet.h and my application document's .cpp file, Guy3Doc.cpp. I have created the following function to retrieve a record set which compiles fine but crashes at runtime. I get a message box on my screen when I attempt to open the CRecordset derived object (CCuHdrSet) that displays the message &quot;failed to create empty document&quot;. When the OK button on the message dialog is clicked, the application exits. If I comment out the hdrSet.Open(....) statement, the application does not terminate and the message dialog does not appear. Clearly I am doing something wrong here but I have not been able to determine my error. I need to use the recordset to obtain results of the query but haven't gotten there yet as I can't get past this error. The code snippet is provided below. If you can help, I would greatly appreciate it.


void CGuy3Doc::DoQuery(void){
CDatabase m_Database;
if(!m_Database.Open(NULL, FALSE, TRUE, &quot;ODBC;DSN=RAMS&quot;)){
AfxMessageBox(&quot;Failed to open the database connection.&quot;);
}
CCuHdrSet hdrSet(&m_Database);
hdrSet.m_strFilter = &quot;&quot;;
// the following statement is all on a single line
// in my actual program.
if(!hdrSet.Open(AFX_DB_USE_DEFAULT_TYPE, &quot;SELECT [TITLE] FROM [TIDCUHDR] WHERE [COMPATIBLE_UNIT] = 'S0440'&quot;) || hdrSet.IsEOF())
{
AfxMessageBox(&quot;Cannot find records.&quot;);
}
// add in use of recordset here
hdrSet.Close();
m_Database.Close();
}
 
Can you say, what error do you get? Check it with CDBException and CDBErrorInfo. John Fill
1c.bmp


ivfmd@mail.md
 
I changed the code as shown below to include a try/catch block for the CDBException object. The message returned was &quot;invalid descriptor index&quot;. The program did not automatically terminate with the inclusion of the exception handler. I have not used try/catch blocks in C++ before so hopefully I did it correctly.

// public function to perform database retrieval of cost data
void CGuy3Doc::DoQuery(void){
try{CDatabase m_Database;
if(!m_Database.Open(NULL, FALSE, TRUE, &quot;ODBC;DSN=RAMS&quot;)){
AfxMessageBox(&quot;Failed to open the database connection.&quot;);
}
CCuHdrSet hdrSet(&m_Database);
hdrSet.m_strFilter = &quot;&quot;;
// next statement is all on one line in actual program
if(!hdrSet.Open(AFX_DB_USE_DEFAULT_TYPE, &quot;SELECT [TITLE] FROM [TIDCUHDR] WHERE [COMPATIBLE_UNIT] = 'S0440'&quot;) || hdrSet.IsEOF())
{
AfxMessageBox(&quot;Cannot find records.&quot;);
}

hdrSet.Close();
m_Database.Close();
}
catch(CDBException *e){
AfxMessageBox(e->m_strError);
}
}
 
How about:
catch(CDBException e){
AfxMessageBox(e.m_strError);
}
?
John Fill
1c.bmp


ivfmd@mail.md
 
I am almost sure that your error comes from the statement:

if(!hdrSet.Open(AFX_DB_USE_DEFAULT_TYPE, &quot;SELECT [TITLE] FROM [TIDCUHDR] WHERE [COMPATIBLE_UNIT] = 'S0440'&quot;) || hdrSet.IsEOF())

I don't understand what you meant with that but I think you are trying to call a method (IeEOF()) that is called before the recordset is opened and therefore crushes.
Anyway the second parameter should be an SQL String or CALL not a || with a method call.

Hopefully I'm right,

s-)

Blessed is he who in the name of justice and good will, shepards the week through the valley of darknees...
 
I tried what BurtanI suggested and removed the &quot;|| hdrSet.IsEOF()&quot; from within the recordset open command but I still received the identical &quot;invalid descriptor index&quot; error.

The try/catch works fine. I changed the way I open the CRecordset derived object and can get a valid recordset back without throwing an exception. However, the filtering method seems to only allow a single value where clause (i.e. &quot;[compatible_unit]='S0440'&quot; but not &quot;[compatible_unit in ('S0440', 'S0460')&quot;. I need to be able to retrieve records based on multiple where clause values.

void CGuy3Doc::DoQuery(void){
try{CDatabase m_Database;
if(!m_Database.Open(NULL, FALSE, TRUE, &quot;ODBC;DSN=RAMS&quot;)){
AfxMessageBox(&quot;Failed to open the database connection.&quot;);
}
CCuHdrSet hdrSet(&m_Database);
// This does not work
hdrSet.m_strFilter = &quot;[COMPATIBLE_UNIT] in ('S0440', S0460')&quot;;
// this does work
hdrSet.m_strFilter = &quot;[COMPATIBLE_UNIT]='S0440'&quot;;
// following statement doesnot work
/* if(!hdrSet.Open(AFX_DB_USE_DEFAULT_TYPE, &quot;SELECT [TITLE] FROM [tidcuhdr]&quot;) || hdrSet.IsEOF())
*/
// this statement does work but I only want certain records based on where clause
if(!hdrSet.Open() || hdrSet.IsEOF())
{
AfxMessageBox(&quot;Cannot find records.&quot;);
}
while(!hdrSet.IsEOF()){
AfxMessageBox(hdrSet.m_TITLE);
hdrSet.MoveNext();
}
hdrSet.Close();
m_Database.Close();
}
catch(CDBException *e){
AfxMessageBox(e->m_strError);
}
}

Thanks for your continuing help and suggestions.
 
I used your code as a starting point which helped considerably. Now, I would like to pass values stored in CString objects to fields in the database that I've opened. How might I do that? Any help would be greatly appreciated.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top