直接访问旧的 MDB 文件

Posted

技术标签:

【中文标题】直接访问旧的 MDB 文件【英文标题】:Directly access older MDB files 【发布时间】:2016-12-06 02:02:57 【问题描述】:

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

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

如果我能找到足够的格式文档,我愿意直接阅读这些文件。我也听说过可以处理这些旧文件的旧 ODBC 或其他类似工具。但是一个要求是我们不需要安装一堆额外的软件。理想情况下,我可以使用 C++ 来完成这一切。

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

注意:This article 表示 MDB 文件的布局;但是,它似乎与我正在使用的文件的内容不匹配。

【问题讨论】:

你能从 Visual Studio 成功连接到这个数据库吗? (Tools--> Connect To Database) 如果是这样,则表明驱动程序可用于此(旧)格式。 绝对不是。尽管我的计算机上安装了 Access,但我的系统上没有任何软件能够读取这些旧的 MDB 文件。 哎哟!甚至没有访问权限??? 我有 Access 2013。它不会读取这些旧文件。而且,如前所述,我们的偏好是在没有 Access 或任何其他软件的情况下读取文件。我需要的只是格式的一些好的文档。 Access 2010 运行时可在microsoft.com/download/details.aspx?id=10910 免费获得,这可能对您有用。 【参考方案1】:

我使用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('\0')) + 1;
         while (pszBuf[1] != _T('\0'));

        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 位 ...

它有:

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

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

【讨论】:

这很有帮助,谢谢。通过一些试验和错误,我能够在我的 Windows 10 机器上工作。需要一些测试来确认客户端也有这些驱动程序。该应用程序较旧并且已经是 32 位,所以我想我会保留它。【参考方案2】:

读取 MS Access .mdb 文件所需的只是安装在目标 PC/服务器上的 MDAC(Microsoft 数据访问组件)。 为了您的方便,所有现代操作系统(如 Vista/Windows 7/8/8.1/10)都预先安装了此组件。如果您必须以 XP 为目标,您可以从 MS 站点下载此组件。如果您需要为您的应用构建安装程序,InstallShield 还附带 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);

【讨论】:

以上是关于直接访问旧的 MDB 文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 服务中打开 mdb 文件

为许多用户通过 PHP 访问打开的 MDB 文件

为访问 mdb 文件创建 OdbcConnection 的 ConnectionString 是啥

编译访问 (mde) 文件的链接表问题

应用程序访问共享文件夹上的 mdb 文件,而客户端上没有 ms 访问权限

如何从 python 访问 .mdb 文件?