Avatar of bowser17
bowser17
 asked on

C++ MFC CDatabase Unhandled Exception, Access violation when calling Open or OpenEx MS Access

When trying to open a MS Access database .mdb using C++ MFC CDatabase object, i try using Open or OpenEx, and i get:
Unhandled exception at 0x00000000 in MPUtilD.exe: 0xC0000005: Access violation reading location 0x00000000.

The mysterious part is this code was working, and now it doesn't.  I thought it may be some database change i made, maybe corrupting something, but i tried repair and compact.  I even tried an older version of the database from a  backup when i know for sure it was working.  Nothing!  I've changed the path, the name of the database, tried slight variations of the connection string... nothing works.  Im super frustrated.

Here is how i build the connection string:
CDatabase db;
CString cnStr;
cnStr.Format("ODBC;DRIVER={MICROSOFT ACCESS DRIVER (*.mdb)};DSN='';DBQ=%s",sFile);
db.OpenEx(cnStr);

sFile is the path to the database, and is passed in.  I check the value of cnStr prior to stepping through OpenEx, and verify the string is good.
Editors IDEsSystem ProgrammingMicrosoft Access

Avatar of undefined
Last Comment
bowser17

8/22/2022 - Mon
rockiroads

Have u got all the latest drivers in place? MDAC and all

Also try a decompile, see if that helps http://www.granite.ab.ca/access/decompile.htm

Compact/Repair doesnt always repair corrupted databases, thats if u have one
so try this

create a brand new database then create a new table there. Does accessing that work?
If so then try importing some tables from the old db into this new db. Does accessing them work?

Another recovery method is to import objects from old db to new db
bowser17

ASKER
I believe my MDAC is up to date, as i mentioned, this worked before, and i actually started a new project and was able to open the DB from the new project with that code.
I dont have any VBA in the database, but i guess i could still try the decompile.  I have Access 2003, however it says in the title bar of the window, Access 2000 file format.  I had also tried the new database, blank, and with tables imported.  None of that works.  Would could have changed in my project?  I am at a loss....  i guess i may be forced to recreate the project from scratch
bowser17

ASKER
I would like to rephrase the question, as this all works on another computer, so its obviously some sort of config, or and environment change.  If possible, can someone give some code method on how to determine what the error actually is?  I tried using a try catch, but the GetLastError = 0.  the try was:

try
{
catch(...)
{
  DWORD le = GetLastError();
}
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
rockiroads

its been a while since Ive done C++ especially using visual c++

lets try something a little easier. A bit of vb. Dont worry u dont need vb installed.
Since u have access, open up a new database then go into modules (alt-f11)
create a new module (right click on project explorer and select insert module

lets try this, note u may need to add the DAO reference. (in vba code window, go to Tools/Reference and select Microsoft DAO Object Library v3.6)

public sub TestOpenDBFromAltSource()
    dim db as dao.database
    dim rs as dao.recordset

    set db = DBEngine(0).OpenDatabase("c:\mydb.mdb")
    set rs=db.openrecordset("select * from sometable")
    if rs.eof = false then
        msgbox "got record " & rs.fields(0).value
    else
        msgbox "no recs"
    end if
    rs.close
    set rs=nothng
    db.Close
    set db=nothing
end function



Note, this is just a test. I want to see what happens if u open your database using another source.


regarding C++, its something like this

CDatabase db;
CString SqlString;
CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile = "c:\mydb.mdb";
      
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);

try {
    db.Open(NULL,false,false,sDsn);
}
catch (CDBException, e)
{
    AfxMessageBox("Got Error : " + e->m_strError);
}
end_catch;
bowser17

ASKER
the vb test works, and the C++ wont catch the CDBException, or CException even, only ...
rockiroads

ok, that means your database is fine, I would say so since it works fine with vb

with C++, did u try fetchng data? example I gave just did a open

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
bowser17

ASKER
As the first message states, its throwing an unhandled exception on the open method.  Im not sure what i can do at this point...
rockiroads

so its falling over on

db.Open(NULL,false,false,sDsn);


what are the other parameters for db.Open? there are 4, last one being your connection string
bowser17

ASKER
i dont recall, but this used to work, and it actually works on the same amchine in a new project which is strange.  I have something else im going to try to fix, maybe i'll get lucky and it will solve that too... (but probably not).
Your help has saved me hundreds of hours of internet surfing.
fblack61
graber

Here is what I have.

1.) you will have to create a database.  I've used Access but that is all that has been available to me.

2.) inside the control panel there is an icon odbc data source.  When you open this there is a tab for user DSN.  Press the add button.  This will allow you to select the database that you created in step 1.

3.) here is a short program for accessing the database.  Here the example was for a simple database containing a last name and first name.
#include <afx.h>
#include <afxdb.h>
#include <conio.h>

void main()
{
  CDatabase *pMyDbase=new CDatabase;
  CRecordset *pMyRecord;
  CString sSQL="SELECT Last, First FROM Person ";
  CString sSQL1;
  CString sFirst;
  CString sSecond;
  CDBVariant dbVFirst;
  CDBVariant dbVSecond;

  sSQL1.Format("WHERE Last = %s;", "Flinstone");
  try
    {
      pMyDbase->OpenEx(_T("DSN=Database"),CDatabase::openReadOnly);
      pMyRecord= new CRecordset(pMyDbase);
      pMyRecord->Open(CRecordset::snapshot,sSQL+sSQL1);
      while(!pMyRecord->IsEOF())
      {
        pMyRecord->GetFieldValue((short)0, sFirst);
        pMyRecord->GetFieldValue(1, dbVSecond);
        pMyRecord->MoveNext();
      }
      pMyDbase->Close();
      getch();
    }
    catch(...)
    {
      pMyDbase->Close();
    }
}
The short on the zero of first element is required.  Why I don't know.  It came down from the microsoft engineers.

Hope that is of some help.  Good luck and good coding.
Gregg


bowser17

ASKER
Ok, not sure if you guys are still watching but i've managed to trace the exception into the tidtable.c code:

_ptiddata __cdecl _getptd (
        void
        )
{
        _ptiddata ptd;
        DWORD   TL_LastError;


        TL_LastError = GetLastError();
        if ( (ptd = FLS_GETVALUE(__tlsindex)) == NULL ) {
            /*
             * no per-thread data structure for this thread. try to create
             * one.
             */
            if ( ((ptd = _calloc_crt(1, sizeof(struct _tiddata))) != NULL) &&
                FLS_SETVALUE(__tlsindex, (LPVOID)ptd) ) {

                /*
                 * Initialize of per-thread data
                 */

                _initptd(ptd);

                ptd->_tid = GetCurrentThreadId();
                ptd->_thandle = (uintptr_t)(-1);
            }
            else
                _amsg_exit(_RT_THREAD); /* write message and die */
            }

        SetLastError(TL_LastError);


        return(ptd);
}

the exception happens on this line:
 if ( (ptd = FLS_GETVALUE(__tlsindex)) == NULL )

I cannot trace anymore into it.  The only thing i've read regarding this is to make sure i am using the correct version of the CRT libs, which i believe i am, /MTd in all libs and exes.
graber

are you trying to open the actual access database directly? I don't know that you can do this using an ODBC connection.  The only way that I have successfully opened an access database directly is ole Database elements.  Copy the source I pushed up and see if it works for you.  At least you will be connecting.  I will see what I can do about creating an ole example.... It I can find some old source.
Mean while try what I pushed up.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
bowser17

ASKER
I don't know if my previous messages are unclear, but the code i have right now used to work.  I have since made some small changes to it and to other libs.  Now it does not work.  When i start a brand new project, use the same code to open the database, it works.  Im not sure what to do next.  I am trying to avoid a complete teardown.
ASKER CERTIFIED SOLUTION
bowser17

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
bowser17

ASKER
I'd like to close the question since no one answered.  Thanks all for trying.