直接访问较旧的MDB文件

Directly access older MDB files

本文关键字:MDB 文件 访问      更新时间:2023-10-16

我有一个C (MFC)应用程序。我的客户需要我添加一个功能才能从某些数据文件中读取。

这些数据文件是MDB文件。它们似乎适用于Microsoft Access的较旧版本(可能是2007年之前的版本,但我无法确认)。

如果我能在其格式上找到足够的文档,我会直接读取这些文件。我还要听到有关旧的ODBC或其他类似工具的信息,这些工具可以与这些旧文件一起使用。但是,一个要求是我们不需要安装一堆其他软件。理想情况下,我可以从C 中完成所有操作。

我可以就如何访问这些数据获得一些建议吗?格式文档在哪里,除了直接阅读自己以外,还有什么其他选择?

注意:本文介绍了MDB文件的布局;但是,它似乎不匹配我正在使用的文件的内容。

我将CDatabase与Microsoft Jet驱动程序一起连接到MDB数据库。

我这样找到正确的驱动程序:

// We now iterate the JET drivers list and locate a valid MDB driver
CString CPTSDatabase::GetJETDriver(bool bAccDbMode)
{
    CString         strDriver;
    CString         strName, strNameLower, strValue;
    CString         strDefaultDriver = _T("Microsoft Access Driver (*.mdb)");
    CString         strDBType = _T("(*.mdb)");
    CStringArray    aryStrDrivers;
    TCHAR           szBuf[2001];
    WORD            cbBufMax = 2000;
    WORD            cbBufOut;
    TCHAR           *pszBuf = szBuf;
    if (SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
    {
#ifdef _WIN64
        strDefaultDriver = _T("Microsoft Access Driver (*.mdb, *.accdb)");
        strDBType = _T("(*.mdb, *.accdb)");
#else
        if (bAccDbMode)
        {
            strDefaultDriver = _T("Microsoft Access Driver (*.mdb, *.accdb)");
            strDBType = _T("(*.mdb, *.accdb)");
        }
#endif
        do 
        {
            strName = CString(pszBuf);
            strNameLower = strName;
            strNameLower.MakeLower();
            if (strNameLower.Find(strDBType) != -1)
            {
                aryStrDrivers.Add(strName);
                if (strName.CollateNoCase(strDefaultDriver) == 0)
                {
                    strDriver = strName;
                    break;
                }
            }
            pszBuf = _tcschr(pszBuf, _T('')) + 1;
        } while (pszBuf[1] != _T(''));
        if (strDriver.IsEmpty() && aryStrDrivers.GetSize() > 0)
        {
            // Try and use the first MDB driver we found
            strDriver = aryStrDrivers.GetAt(0);
        }
    }
    // Make a note of the driver
    AfxGetApp()->WriteProfileString(_T("Options"), _T("JET Connection Driver"), strDriver);
    return strDriver;
}

如果您知道要使用哪个驱动程序,则仅使用它。然后打开数据库:

// Opens the database (gets closed in destructor)
void CPTSDatabase::OpenDatabase(bool bAccDbMode, CString strPassword)
{
    CString     strDBConnectString;
    CString     strDriver;
    if (m_dbDatabase.IsOpen())
        return;
    if (DatabaseExist(m_strDatabasePath))
    {
        // AJT v10.5.0 Take into account the DB mode
        strDriver = GetJETDriver(bAccDbMode);
        // Take into account the DB password (decrypted!)
        strDBConnectString.Format(_T("Driver={%s};DBQ=%s;Pwd=%s"),
            strDriver, m_strDatabasePath,
            CPTSTools::DecryptDatabasePassword(strPassword));
        m_dbDatabase.OpenEx(strDBConnectString, CDatabase::noOdbcDialog);
    }
}

但是一个警告的单词 ....我以自己的计算机为例....

我的计算机是Windows 10 64位...

它具有:

  • a 64 ACCDB Microsoft数据库驱动程序
  • a 32 MDB Microsoft数据库驱动程序

没有64位MDB驱动程序。因此,如果您想使用MDB数据库,请确保以32位模式构建应用程序。

您需要读取MS访问.MDB文件的所有内容是 MDAC (Microsoft Data Access组件)安装在目标PC/Server上。所有现代的OSS(例如Vista/Windows 7/8/8.1/10)都有此组件的预安装,以说明您的说服力。如果您必须定位XP,则可以从MS站点下载此组件。如果您需要为应用程序构建安装程序,则安装罩也带有MDAC 2.7合并模块。

您可以简单地使用标准的MFC类来与数据库一起使用:

CDatabase database;
CString sDsn;
CString sFile = _T("D:\Projects\DB\Test.mdb");
// Build ODBC connection string
sDsn.Format(_T("ODBC;DRIVER={%s};DSN='';DBQ=%s"), _T("MICROSOFT ACCESS DRIVER (*.mdb)"), sFile);
try
{
    // Open the database
    database.Open(NULL, FALSE, FALSE, sDsn);
    // Allocate the recordset
    CRecordset recset( &database );
    // Build the SQL statement
    CString sSqlString =  _T("SELECT Field1, Field2 from MyTable");
    // Execute the query
    recset.Open(CRecordset::forwardOnly, sSqlString, CRecordset::readOnly);
    // Loop through each record
    while( !recset.IsEOF() )
    {
        // Copy each column into a variable
        CString sField1;
        CString sField2;
        recset.GetFieldValue(_T("Field1"), sField1);
        recset.GetFieldValue(_T("Field2"), sField2);
        // goto next record
        recset.MoveNext();
    }
    // Close the database
    database.Close();
}
catch(CDBException* e)
{
    // If a database exception occured, show error msg
    AfxMessageBox(_T("Database error: ") + e->m_strError);
}