Программирование данных в Microsoft Access 2010

Сводка:  в статье приведены сведения о разработке как собственного (C, C++, Java, VBA), так и управляемого (C#, Visual Basic.NET) кода доступа к данным в Microsoft Office Access 2007 и Microsoft Access 2010. В статье также приведены сведения об архитектуре Access, ядре ACE и поставщиках данных, 32- и 64-разрядных платформах, а также о факторах, которые необходимо учитывать при выборе оптимальной технологии доступа к данным для нового или устаревшего проекта для работы с базами данных.

Дата последнего изменения: 24 апреля 2015 г.

Применимо к: Access 2007 | Access 2010 | Office 2010

В этой статье
Обзор
Архитектура ядра Microsoft Access
Обзор технологий доступа к данным
Данные о производительности
Использование 32- и 64-разрядных поставщиков ACE
Факторы, влияющие на выбор технологии доступа к данным
Устаревшие методы доступа к данным
Заключение

Опубликовано:  сентябрь 2010 г.

Предоставлено:  Александр Якшич, Microsoft Corporation

Содержание

  • Обзор

  • Архитектура ядра Microsoft Access

  • Обзор технологий доступа к данным

  • Данные о производительности

  • Использование 32- и 64-разрядных поставщиков ACE

  • Факторы, влияющие на выбор технологии доступа к данным

  • Устаревшие методы доступа к данным

  • Заключение

Щелкните, чтобы скопировать код  Загрузить код

Обзор

В данной технической статье рассматриваются различные механизмы программного доступа к данным в Access 2007 и Access 2010. Здесь рассматривается ядро Access, также известное как ядро СУБД Microsoft Access (ACE). Если вы являетесь разработчиком баз данных и хотите больше узнать о возможностях, доступных при разработке решений для доступа к данным, хранящимся в базах данных Access, эта статья для вас. Цель данной статьи не в том, чтобы подробно рассмотреть каждый интерфейс доступа к данным, а в том, чтобы дать читателю представление об архитектуре ядра ACE для лучшего понимания используемой модели программирования. Прилагаемые к статье примеры кода написаны как на традиционных языках программирования (C, C++, Java и VBA), так и на языках .NET Framework (C# и Visual Basic.NET), что позволяет быстро приступить к работе даже тем, кто раньше никогда не программировал на некоторых из этих языков.

В данной технической статье даются ответы на указанные ниже вопросы.

  • Будет ли мое устаревшее 32-разрядное приложение работать с 64-разрядным программным обеспечением Access?

  • Какой способ программной работы с базами данных Access обеспечивает максимальное быстродействие?

  • Можно ли подключиться к ядру ACE с помощью кода на языке программирования C (ANSI/ISO C) или даже Java?

  • Можно ли использовать устаревший код Microsoft Foundation Classes (MFC) Data Access Object (DAO) для работы с базами данных ACCDB?

Примеры кода

В данной технической статье представлены девять готовых программ, созданных в Microsoft Visual Studio 2008 и доступных для загрузки.

В каждом примере один и тот же алгоритм доступа к данным реализован на различных языках программирования и с использованием различных технологий доступа к данным, таких как DAO, OLE DB, ADO.NET, ADO, ODBC и JDBC. Выходные данные программ практически идентичны. В примерах демонстрируются ключевые возможности программного доступа к данным, например построение строки подключения с использованием надежного пароля для расшифровки базы данных, подключение к зашифрованной базе данных, построение и выполнение SQL-запроса, работа со схемой и набором записей и загрузка отсортированных данных.

Поскольку ядро Access не является компонентом операционной системы Windows, ядро ACE и его поставщики необходимо установить на локальный компьютер. Дополнительные сведения см. в разделе Где можно получить ядро ACE?.

В данной технической статье также приведены Данные о производительности для всех поставщиков данных, используемых в примерах кода.

Для кого предназначена данная статья

Предмет технологий доступа к данным весьма обширен, а поскольку данное руководство предназначено для широкого круга разработчиков, приведенные здесь материалы будут полезны для каждого разработчика, работающего с данными Access на уровне бизнес-логики или приложений. Кроме того, данная статья написана с прицелом на ИТ-специалистов, студентов и энтузиастов, интересующихся общими вопросами программирования баз данных.

Предполагается, что читатель знаком со средой Visual Studio, основами программирования (структурного программирования или программирования для .NET Framework), а также с реляционными базами данных и SQL. Также предполагается, что читатель умеет создавать таблицы и запросы в любом из предыдущих выпусков Microsoft Access.

Примечание

Если в документе не указана конкретная версия Microsoft Access (например Microsoft Access 2003), предполагается, что соответствующие сведения относятся и к Microsoft Office Access 2007, и к Microsoft Access 2010.

Архитектура ядра Microsoft Access

На рис. 1 показано, как Access (пользовательский интерфейс) и ACE (ядро) формируют полнофункциональную систему управления базами данных (СУБД).

Рис. 1. Концептуальное представление Access 2010

Высокоуровневая концептуальная диаграмма Access 2010

Пользовательский интерфейс Access отвечает за взаимодействие с пользователем и позволяет просматривать, редактировать и использовать данные с помощью форм, отчетов, запросов, макросов, мастеров и т. д. С другой стороны, ядро Microsoft Access (ACE) предоставляет основные службы для управления базами данных, которые перечислены ниже.

  • Хранение данных ─ сохранение данных в файловой системе.

  • Определение данных ─ создание, редактирование и удаление структур для хранения данных, например таблиц и полей.

  • Обеспечение целостности данных ─ принудительное применение реляционных правил, предотвращающих повреждение данных.

  • Работа с данными ─ добавление, изменение, удаление и сортировка существующих данных.

  • Извлечение данных ─ извлечение данных из системы с помощью SQL-запросов.

  • Шифрование данных ─ защита данных от несанкционированного использования.

  • Совместное использование данных ─ предоставление общего доступа к данным в многопользовательской сетевой среде.

  • Публикация данных ─ работа в клиентской или серверной веб-среде.

  • Импорт, экспорт и связывание данных ─ работа с данными из различных источников.

С точки зрения доступа к данным Access можно рассматривать как способ графического представления ядра ACE для пользователей.

Где можно получить ядро ACE?

Для запуска примеров кода, приведенных в данной статье, на компьютере должно быть установлено ядро ACE, т. е. один из указанных ниже продуктов Access 2010 (или Office Access 2007).

Примечание

Драйверы ядра СУБД Microsoft Access 2007 и 2010 позволяют разработчикам решений создавать средства для чтения и записи данных в файлы Office в таких форматах, как ACCDB, XLSX и XLSB. Это позволяет разработчикам решений выполнять чтение и запись форматов файлов Office на сервере (например на SQL-сервере), не устанавливая Office. Однако эти драйверы не лицензированы для использования в качестве автономного хранилища данных.

Что насчет ядра Microsoft JET?

До выпуска Access 2007 в Access использовалось ядро Microsoft Joint Engine Technology (JET). Хотя ядро JET обычно рассматривается как компонент Access, оно является отдельным продуктом. С момента выпуска Microsoft Windows 2000 ядро JET было включено в состав операционной системы Windows, после чего распространялось и обновлялось в составе компонентов Microsoft Data Access Components (MDAC). После выпуска Access 2007 ядро JET было признано устаревшим и было исключено из состава MDAC. Вместо этого ядра в Access теперь используется интегрированное и усовершенствованное ядро ACE, разработка которого началась с создания снимка исходного кода JET.

Ядро ACE полностью обратно совместимо с предыдущими версиями JET, что позволяет выполнять чтение и запись данных в MDB-файлы из предыдущих версий Access. Поскольку ядро теперь отдано группе разработчиков Access, другие разработчики могут быть уверены в том, что их решения для Access не только продолжат работать в будущем, но станут быстрее, надежнее и получат поддержку новых возможностей. Например, с выпуском Access 2010 в ядре ACE, в числе прочих усовершенствований, была реализована поддержка 64-разрядной версии и улучшена интеграция с технологиями и веб-службами SharePoint. Корпорация Microsoft обязуется поддерживать Access в качестве платформы разработки.

Обзор технологий доступа к данным

Корпорация Microsoft предоставляет несколько способов работы с базами данных Access. Ниже перечислены API-интерфейсы и уровни доступа к данным, используемые при программной работе с Access.

  • Data Access Objects (DAO)

  • Object Linking and Embedding, Database (OLE DB)

  • ADO.NET

  • ActiveX Data Objects (ADO)

  • Open Database Connectivity (ODBC)

В ядре ACE реализованы поставщики для трех из указанных выше технологий: DAO, OLE DB и ODBC. Поставщики ACE DAO, ACE OLE DB и ACE ODBC распространяются вместе с Access (за исключением технологии ADO, которая по-прежнему входит в состав Microsoft Windows DAC). Множество других программных интерфейсов, поставщиков и системных платформ доступа к данным, включающих ADO и ADO.NET, построены на базе этих трех поставщиков ACE. На рис. 2 приведена схема, дающая общее представление о компонентах Access.

Рис. 2. Архитектура ядра ACE в среде программного доступа к данным

Схема архитектуры ACE

В данной статье документированы методы доступа к данным, перечисленные в приведенной ниже таблице.

Таблица 1. Методы доступа к данным

Имя поставщика

Метод доступа к данным

Сведения о подключении

Поддерживаемые языки

ACE DAO

Пример непосредственного использования DAO

Acedao.tlh (создан на основе библиотеки acedao.dll);

acedao.dll

C++

Пример использования DAO на VBA

Set db = CurrentDb()

Запускается в среде редактора Visual Basic

VBA

ACE OLE DB

Пример использования OLE DB с помощью библиотеки ATL

Microsoft.ACE.OLEDB.12.0

<Atldbcli.h> и <Atldbsch.h>; Aceoledb.dll

C++

ADO.NET

Пример использования ADO.NET на C#

Microsoft.ACE.OLEDB.12.0

Используется System.Data.OleDb;

C#

Пример использования ADO.NET на Visual Basic.NET

Пример использования ADO.NET на Visual Basic.NET

Microsoft.ACE.OLEDB.12.0

Импортируется System.Data.OleDb

Импортируется System.Console

Visual Basic.NET

ADO

Пример использования ADO

Msado15.tlh (создан на основе библиотеки Msado15.dll);

Устанавливается с MDAC 2.8 или Windows DAC 6.0.

C++

ACE ODBC

Пример непосредственного использования ODBC

Driver={драйвер Microsoft Access (*.mdb, *.accdb)};DBQ=путь к MDB- или ACCDB-файлу

<Sqlext.h>;

Aceodbc.dll;

C/C++

Пример использования ODBC с помощью MFC

Driver={драйвер Microsoft Access (*.mdb, *.accdb)};DBQ=путь к MDB- или ACCDB-файлу

<Afxdb.h>;

Aceodbc.dll;

C++

Пример использования JDBC-ODBC

jdbc:odbc:DRIVER=драйвер Microsoft Access (*.mdb, *.accdb);DBQ=путь к MDB- или ACCDB-файлу

Java

Дополнительные сведения, а также список методов доступа к данным, устаревших с выпуском Access 2007, см. в разделе Устаревшие методы доступа к данным.

DAO

Изначально DAO был единственным методом доступа к данным, доступным разработчикам Access.

Пример непосредственного использования DAO

Данный метод обеспечивает наилучшую поддержку новых возможностей, появившихся в Access 2007, поскольку он предоставляет большую часть функций ядра ACE. При непосредственном использовании DAO применяется библиотека Acedao.dll. Чтобы скомпилировать этот код, воспользуйтесь макросом #import для создания TLH-заголовка, указав директиву, аналогичную приведенной в примере ниже.

#import <C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\OFFICE14\\ACEDAO.dll>  \
    rename( "EOF", "AdoNSEOF" )

В зависимости от разрядности операционной системы, для которой компилируется код (32 или 64 бита), может потребоваться удалить из пути компонент "(x86)". Для этого проверьте раздел реестра Path типа REG_SZ по одному из указанных ниже путей реестра.

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\InstallRoot

  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\InstallRoot

Поскольку подключение осуществляется непосредственно к ядру, в сведениях о подключении имеет значение только расположение базы данных.

_bstr_t bstrConnect = "C:\\Northwind.accdb";

В приведенном ниже примере кода извлекается схема и данные.

Примечание

Чтобы получить полный код приложений, загрузите соответствующий пример.

// Create an instance of the engine
DAO::_DBEngine* pEngine = NULL;

// The CoCreateInstance helper function provides a convenient shortcut by connecting 
// to the class object associated with the specified CLSID, creating an 
// uninitialized instance, and releasing the class object. 
hr = CoCreateInstance(
    __uuidof(DAO::DBEngine),
    NULL,
    CLSCTX_ALL,
    IID_IDispatch,
    (LPVOID*)&pEngine);
if (SUCCEEDED(hr) && pEngine)
{
    // COM errors are handled by C++ try/catch block
    try
    {
        DAO::DatabasePtr pDbPtr = NULL;
        pDbPtr = pEngine->OpenDatabase(bstrConnect, false, false, ";PWD=1L0v3Acce55;");
        if (pDbPtr)
        {
            cout<<DAM<<": Successfully connected to database. Data source name:\n  "
                <<pDbPtr->GetName()<<endl;

            // Prepare SQL query.
            _bstr_t query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";
            cout<<DAM<<": SQL query:\n  "<<query<<endl;

            // Run the query and create a record set
            DAO::RecordsetPtr pRS = NULL;
            pRS = pDbPtr->OpenRecordset(query, _variant_t(DAO::dbOpenDynaset));
            if (pRS && 0 < pRS->RecordCount)
            {
                cout<<DAM<<": Retrieve schema info for the given result set: "<<endl;
                DAO::FieldsPtr pFields = NULL;
                pFields = pRS->GetFields();
                if (pFields && pFields->Count > 0)
                {
                    for (short column = 0; column < pFields->Count; column++)
                    {
                        cout<<" | "<<pFields->GetItem(column)->GetName();
                    }
                    cout<<endl;
                }
                else
                {
                    cout<<DAM<<": Error: Number of fields in the result set is 0."<<endl;
                }

                cout<<DAM<<": Fetch the actual data: "<<endl;
                // Loop through the rows in the result set
                while (!pRS->AdoNSEOF)
                {
                    for (short column = 0; column < pFields->Count; column++)
                    {
                        cout<<" | "<<_bstr_t(pFields->GetItem(column)->GetValue());
                    }
                    cout<<endl;
                    pRS->MoveNext();
                }
                cout<<DAM<<": Total Row Count: "<<pRS->RecordCount<<endl;
            }

            // Close record set and database
            pRS->Close();
            pDbPtr->Close();
            pDbPtr = NULL;
        }
        else
        {
            cout<<DAM<<": Unable to connect to data source: "<<bstrConnect<<endl;
        }
    }
    catch(_com_error& e)
    {
        cout<<DAM<<": _com_error: "<<e.ErrorMessage()<<endl;
    }
    
    pEngine->Release();
    pEngine = NULL;
    cout<<DAM<<": Cleanup. Done."<<endl;
}
else
{
    cout<<DAM<<": Cannot instantiate DBEngine object."<<endl;
}

В приведенном ниже примере показаны выходные данные программы.

Direct DAO: Successfully connected to database. Data source name:
  C:\Northwind.accdb
Direct DAO: SQL query:
  SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;
Direct DAO: Retrieve schema info for the given result set:
 | Company | First Name
Direct DAO: Fetch the actual data:
 | Company A | Anna
 | Company AA | Karen
 | Company B | Antonio
 | Company BB | Amritansh
 | Company C | Thomas
 | Company CC | Soo Jung
 | Company D | Christina
 | Company E | Martin
 | Company F | Francisco
 | Company G | Ming-Yang
 | Company H | Elizabeth
 | Company I | Sven
 | Company J | Roland
 | Company K | Peter
 | Company L | John
 | Company M | Andre
 | Company N | Carlos
 | Company O | Helena
 | Company P | Daniel
 | Company Q | Jean Philippe
 | Company R | Catherine
 | Company S | Alexander
 | Company T | George
 | Company U | Bernard
 | Company V | Luciana
 | Company W | Michael
 | Company X | Jonas
 | Company Y | John
 | Company Z | Run
Direct DAO: Total Row Count: 29
Direct DAO: Cleanup. Done.

Пример использования DAO на VBA

Приведенный ниже пример кода запускается в среде Access VBA/VBE для текущей базы данных.

    Public Sub VBADAO()
        Dim DAM As String
        Dim db As DAO.Database
        Dim rst As DAO.Recordset
        Dim query As String
            
        DAM = "VBA DAO"
    
        ' Open pointer to current database
        Set db = CurrentDb()
       
        Debug.Print DAM & ": Successfully connected to database. Data source name: " & _
            vbNewLine & "  " & db.Name
        
        ' Prepare SQL query
        query = "SELECT Customers.[Company], Customers.[First Name] " & _
            "FROM Customers " & _
            "ORDER BY Customers.[Company] ASC"
            
        Debug.Print DAM & ": SQL Query: " & _
            vbNewLine & "  " & query
    
        ' Run the query and create a record set
        Set rst = db.OpenRecordset(query)
        
        Debug.Print DAM & ": Retrieve schema info for the given result set: "
        For i = 0 To rst.Fields.Count - 1
            Debug.Print " | " & rst.Fields(i).Name
        Next i
            
        Debug.Print DAM & ": Fetch the actual data: "
        Do While Not rst.EOF
            Debug.Print " | " & rst![Company] & " | " & rst![First Name]
            rst.MoveNext
        Loop
        
        Debug.Print DAM & ": Total Row Count: " & rst.RecordCount
        Debug.Print DAM & ": Cleanup. Done. "
    
        rst.Close
        db.Close
    End Sub

OLE DB

OLE DB — это программный интерфейс для доступа к данным на уровне системы, разработанный корпорацией Microsoft. OLE DB представляет собой спецификацию, а не набор компонентов или файлов. Эта технология лежит в основе ADO и является источником данных для ADO.NET. В OLE DB определяется набор COM-интерфейсов, инкапсулирующих различные службы системы управления базами данных для обслуживания клиентов. OLE DB — это открытый стандарт для доступа ко всем типам данных, включая базы данных Access. OLE DB поддерживает требования к разработке, в том числе возможность создания клиентов для интерфейсных баз данных и бизнес-объектов промежуточного уровня с помощью динамических подключений к данным в реляционных базах данных и других хранилищах.

Пример использования OLE DB с помощью библиотеки ATL

В данном примере используется библиотека шаблонных классов ATL, подключаемая путем включения заголовочных файлов <Atldbcli.h> и <Atldbsch.h>. В сведениях о подключении указывается поставщик данных Microsoft.ACE.OLEDB.12.0, реализованный в библиотеке Aceoledb.dll.

LPCOLESTR lpcOleConnect = 
    L"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Northwind.accdb;Jet OLEDB:Database Password=1L0v3Acce55;";

В приведенном ниже примере кода извлекается схема и данные.

// To initialize the connection to a database using an OLE DB provider, 
// two ATL classes are needed: CDataSource and CSession;
CDataSource dbDataSource;
CSession dbSession;

// Uses the ATL string conversion macros to convert between character encodings
USES_CONVERSION;

// Open the connection and initialize the data source specified by the passed 
// initialization string.
hr = dbDataSource.OpenFromInitializationString(lpcOleConnect);
if (FAILED(hr))
{
    cout<<DAM<<": Unable to connect to data source "<<OLE2T(lpcOleConnect)<<endl;
}
else
{
    hr = dbSession.Open(dbDataSource);
    if (FAILED(hr))
    {
        cout<<DAM<<": Couldn't create session on data source "<<OLE2T(lpcOleConnect)<<endl;
    }
    else
    {
        CComVariant var;
        hr = dbDataSource.GetProperty(DBPROPSET_DATASOURCEINFO, DBPROP_DATASOURCENAME, &var);
        if (FAILED(hr) || (var.vt == VT_EMPTY))
        {
            cout<<DAM<<": No Data Source Name Specified."<<endl;
        }
        else
        {
            cout<<DAM<<": Successfully connected to database. Data source name:\n  "
                <<COLE2T(var.bstrVal)<<endl;
            
            // Prepare SQL query.
            LPCOLESTR query = L"SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";
            cout<<DAM<<": SQL query:\n  "<<OLE2T(query)<<endl;

            // Run the query and create a record set
            CCommand<CDynamicStringAccessor> cmd;
            hr = cmd.Open(dbSession, query);
            DBORDINAL colCount = cmd.GetColumnCount();
            if (SUCCEEDED(hr) && 0 < colCount)
            {
                cout<<DAM<<": Retrieve schema info for the given result set: "<<endl;
                DBORDINAL cColumns;
                DBCOLUMNINFO* rgInfo = NULL;
                OLECHAR* pStringsBuffer = NULL;
                cmd.GetColumnInfo(&cColumns, &rgInfo, &pStringsBuffer);
                for (int col=0; col < (int)colCount; col++)
                {
                    cout<<" | "<<OLE2T(rgInfo[col].pwszName);
                }
                cout<<endl;

                cout<<DAM<<": Fetch the actual data: "<<endl;
                int rowCount = 0;
                CRowset<CDynamicStringAccessor>* pRS = (CRowset<CDynamicStringAccessor>*)&cmd;
                // Loop through the rows in the result set
                while (pRS->MoveNext() == S_OK)
                {
                    for (int col=1; col <= (int)colCount; col++)
                    {
                        CHAR* szValue = cmd.GetString(col);
                        cout<<" | "<<szValue;
                    }
                    cout<<endl;
                    rowCount++;
                }
                cout<<DAM<<": Total Row Count: "<<rowCount<<endl;
            }                   
            else
            {
                cout<<DAM<<": Error: Number of fields in the result set is 0."<<endl;
            }
        }  
    }
}

dbDataSource.Close();
dbSession.Close();

cout<<DAM<<": Cleanup. Done."<<endl;

ADO.NET

ADO.NET обеспечивает единообразный и комплексный доступ к различным источникам данных в (управляемой) среде .NET. В ADO.NET используются управляемые поставщики .NET, в которых, в свою очередь, используются такие API-интерфейсы, как OLE DB и ODBC. В данной статье приведены два примера использования ADO.NET (на языках C# и Visual Basic.NET), в каждом из которых в качестве уровня доступа к данных используется OLE DB.

Пример использования ADO.NET на C#

Ниже приведен пример кода ADO.NET на языке C#.

// Connection string for ADO.NET via OleDB
OleDbConnection cn = 
    new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Northwind.accdb;Jet OLEDB:Database Password=1L0v3Acce55;");

// Prepare SQL query
string query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";
OleDbCommand cmd = new OleDbCommand(query, cn);

try
{
    cn.Open();
    Console.WriteLine("{0}: Successfully connected to database. Data source name:\n {1}", 
        DAM, cn.DataSource);
    Console.WriteLine("{0}: SQL query:\n {1}", DAM, query);

    // Run the query and create a record set
    OleDbDataReader dr = cmd.ExecuteReader();
    Console.WriteLine("{0}: Retrieve schema info for the given result set:", DAM);
    for (int column = 0; column < dr.FieldCount; column++)
    {
        Console.Write(" | {0}", dr.GetName(column));
    }
    Console.WriteLine("\n{0}: Fetch the actual data: ", DAM);
    int row = 0;
    while (dr.Read())
    {
        Console.WriteLine(" | {0} | {1} ", dr.GetValue(0), dr.GetValue(1));
        row++;
    }
    Console.WriteLine("{0}: Total Row Count: {1}", DAM, row);
    dr.Close();
}
catch (OleDbException ex)
{
    Console.WriteLine("{0}: OleDbException: Unable to connect or retrieve data from data source: {1}.",
        DAM, ex.ToString());
}
catch (Exception ex)
{
    Console.WriteLine("{0}: Exception: Unable to connect or retrieve data from data source: {1}.",
        DAM, ex.ToString());
}
finally
{
    cn.Close();
    Console.WriteLine("{0}: Cleanup. Done.", DAM);
}

Пример использования ADO.NET на Visual Basic.NET

Ниже приведен пример кода ADO.NET на языке Visual Basic.NET.

' Connection string for ADO.NET via OleDB
Dim cn As OleDbConnection = 
    New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Northwind.accdb;Jet OLEDB:Database Password=1L0v3Acce55;")
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader

Try
    cn.Open()
    WriteLine(DAM + ": : Successfully connected to database. Data source name:" + ControlChars.Lf + "  " + cn.DataSource)
    ' Prepare SQL query.
    Dim query As String = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;"
    WriteLine(DAM + ": SQL Query:" + ControlChars.Lf + "  " + query)

    ' Run the query and create a record set
    cmd = New OleDbCommand(query, cn)
    dr = cmd.ExecuteReader
    WriteLine(DAM + ": Retrieve schema info for the given result set:  ")
    Dim column, row As Integer
    For column = 0 To dr.FieldCount - 1
        Write(" | " + dr.GetName(column))
    Next column
    WriteLine(ControlChars.Lf + DAM + ": Fetch the actual data:  ")
    row = 0
    While dr.Read()
        WriteLine(" | " + dr(0) + " | " + dr(1))
        row += 1
    End While
    WriteLine(DAM + ": Total Row Count: " + row.ToString())
    dr.Close()
Catch ex As OleDbException
    WriteLine(ControlChars.Lf + DAM + ": OleDbException: Unable to connect or retrieve data from data source: " + ex.Message())
Catch ex As Exception
    WriteLine(ControlChars.Lf + DAM + ": Exception: Unable to connect or retrieve data from data source: " + ex.Message())
Finally
    cn.Close()
    WriteLine(DAM + ": Cleanup. Done.")
End Try

ADO

ActiveX Data Objects (ADO) предоставляет для поставщиков данных OLE DB COM-интерфейс, работающий на уровне приложений. Хотя по сравнению с непосредственным использованием OLE DB производительность ADO ниже, эта технология проста в изучении и использовании. ADO предоставляет программистам на C++ доступ к интерфейсам OLE DB. Большинству разработчиков обычно не требуются такие низкоуровневые средства контроля, как управление ресурсами памяти и агрегирование компонентов, которые OLE DB предоставляет при доступе к данным.

В отличие от DAO, где предоставлялись функции одного ядра СУБД, в ADO используется общая модель программирования для универсального доступа к данным.

Пример использования ADO

В ADO используется библиотека Msado15.dll, входящая в состав MDAC 2.8 и более поздних версий. Чтобы скомпилировать этот код, воспользуйтесь макросом #import для создания TLH-заголовка, указав директиву, аналогичную приведенной в примере ниже.

#import <C:\\Program Files\\Common Files\\System\\ado\\msado15.dll>  \
    rename( "EOF", "AdoNSEOF" )

В сведениях о подключении указывается поставщик данных Microsoft.ACE.OLEDB.12.0, реализованный в библиотеке Aceoledb.dll.

_bstr_t bstrConnect = 
    "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Northwind.accdb;Jet OLEDB:Database Password=1L0v3Acce55;";

В приведенном ниже примере кода извлекается схема и данные.

// COM errors are handled by C++ try/catch block
try
{
    ADODB::_ConnectionPtr pConn("ADODB.Connection");
    hr = pConn->Open(bstrConnect, "admin", "", ADODB::adConnectUnspecified);
    if (SUCCEEDED(hr))
    {
        cout<<DAM<<": Successfully connected to database. Data source name:\n  "
           <<pConn->GetConnectionString()<<endl;

        // Prepare SQL query.
        _bstr_t query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";
        cout<<DAM<<": SQL query:\n  "<<query<<endl;

        // Run the query and create a record set
        ADODB::_RecordsetPtr pRS("ADODB.Recordset");
        hr = pRS->Open(query, 
                _variant_t((IDispatch *) pConn, true), 
                ADODB::adOpenUnspecified,
                ADODB::adLockUnspecified, 
                ADODB::adCmdText);
        if (SUCCEEDED(hr))
        {
            cout<<DAM<<": Retrieve schema info for the given result set: "<<endl;
            ADODB::Fields* pFields = NULL;
            hr = pRS->get_Fields(&pFields);
            if (SUCCEEDED(hr) && pFields && pFields->GetCount() > 0)
            {
                for (long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
                {
                    cout<<" | "<<_bstr_t(pFields->GetItem(nIndex)->GetName());
                }
                cout<<endl;
            }
            else
            {
                cout<<DAM<<": Error: Number of fields in the result set is 0."<<endl;
            }

            cout<<DAM<<": Fetch the actual data: "<<endl;
            int rowCount = 0;
            while (!pRS->AdoNSEOF)
            {
                for (long nIndex=0; nIndex < pFields->GetCount(); nIndex++)
                {
                    cout<<" | "<<_bstr_t(pFields->GetItem(nIndex)->GetValue());
                }
                cout<<endl;
                pRS->MoveNext();
                rowCount++;
            }
            cout<<DAM<<": Total Row Count: "<<rowCount<<endl;
        }
        
        pRS->Close();
        pConn->Close();
        cout<<DAM<<": Cleanup. Done."<<endl;
    }
    else
    {
        cout<<DAM<<": Unable to connect to data source: "<<bstrConnect<<endl;
    }
}
catch(_com_error& e)
{
    cout<<DAM<<": _com_error: "<<e.Description()<<endl;
}

ODBC

ODBC (Open Database Connectivity) — это самая старая из технологий доступа данных, используемых корпорацией Microsoft. Эта технология позволяет создать общую базу кода для обеспечения доступа к различным реляционным источникам данных. Ее методы предоставляются в традиционном, не объектно-ориентированном API-интерфейсе в стиле языка C.

Пример непосредственного использования ODBC

Этот метод доступа к данным рекомендуется использовать только для обслуживания существующих приложений либо при работе с ANSI/ISO C. В примере кода ниже приведены сведения о подключении для непосредственного использования ODBC с помощью драйвера {драйвер Microsoft Access (*.mdb, *.accdb)}, реализованного в библиотеке Aceodbc.dll путем включения заголовочного файла <Sqlext.h>.

SQLCHAR szDSN[256] = 
    "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ=C:\\Northwind.accdb;PWD=1L0v3Acce55;";

В приведенном ниже примере кода извлекается схема и данные.

HENV    hEnv;
HDBC    hDbc;

/* ODBC API return status */
SQLRETURN  rc;

SQLSMALLINT  iConnStrLength2Ptr;
SQLCHAR      szConnStrOut[255];

SQLCHAR* query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";

SQLCHAR         chval1[128], chval2[128], colName[128];
SQLINTEGER      ret1, ret2;

/* Number of rows and columns in result set */
SQLINTEGER      rowCount = 0;
SQLSMALLINT     fieldCount = 0, column = 0;
HSTMT           hStmt;

/* Allocate an environment handle */
rc = SQLAllocEnv(&hEnv);
/* Allocate a connection handle */
rc = SQLAllocConnect(hEnv, &hDbc);

/* Connect to the 'Northwind 2007.accdb' database */
rc = SQLDriverConnect(hDbc, NULL, szDSN,  _countof(szDSN), 
szConnStrOut, 255, &iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT);
if (SQL_SUCCEEDED(rc)) 
{
    printf("%s: Successfully connected to database. Data source name: \n  %s\n", 
       DAM, szConnStrOut);

    /* Prepare SQL query */
    printf("%s: SQL query:\n  %s\n", DAM, query);

    rc = SQLAllocStmt(hDbc,&hStmt);
    rc = SQLPrepare(hStmt, query, SQL_NTS);
   
    /* Bind result set columns to the local buffers */ 
    rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, chval1, 128, &ret1);
    rc = SQLBindCol(hStmt, 2, SQL_C_CHAR, chval2, 128, &ret2);
   
    /* Run the query and create a record set */
    rc = SQLExecute(hStmt); 
    if (SQL_SUCCEEDED(rc)) 
    {
        printf("%s: Retrieve schema info for the given result set:\n", DAM);
        SQLNumResultCols(hStmt, &fieldCount);
        if (fieldCount > 0)
        {
            for (column = 1; column <= fieldCount; column++)
            {
                SQLDescribeCol(hStmt, column,
                    colName, sizeof(colName), 0, 0, 0, 0, 0);
                printf(" | %s", colName);    
            }
            printf("\n");
        }
        else
        {
            printf("%s: Error: Number of fields in the result set is 0.\n", DAM);
        }

        printf("%s: Fetch the actual data:\n", DAM);
        /* Loop through the rows in the result set */
        rc = SQLFetch(hStmt);
        while (SQL_SUCCEEDED(rc)) 
        {
            printf(" | %s | %s\n", chval1, chval2);
            rc = SQLFetch(hStmt);
            rowCount++;
        };

        printf("%s: Total Row Count: %d\n", DAM, rowCount);
        rc = SQLFreeStmt(hStmt, SQL_DROP);
    }
}
else
{
    printf("%s: Couldn't connect to %s.\n", DAM, szDSN);
}

/* Disconnect and free up allocated handles */
SQLDisconnect(hDbc);
SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);

printf("%s: Cleanup. Done.\n", DAM);

Пример использования ODBC с помощью MFC

В примере кода ниже приведены сведения о подключении для MFC ODBC, где используется драйвер {драйвер Microsoft Access (*.mdb, *.accdb)}, реализованный в библиотеке Aceodbc.dll путем включения заголовочного файла <Afxdb.h>.

LPCTSTR lpszConnect = 
    _T("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ=C:\\Northwind.accdb;PWD=1L0v3Acce55;");

В приведенном ниже примере кода извлекается схема и данные.

BOOL result = TRUE;
CDatabase db;

TRY
{
    result = db.OpenEx(lpszConnect, 
        CDatabase::openReadOnly |
        CDatabase::noOdbcDialog);
    if (FALSE == result)
    {
        cout<<DAM<<": Unable to connect to data source "<<lpszConnect<<endl;
        return result;
    }

    cout<<DAM<<": Successfully connected to database. Data source name:\n  "
        <<db.GetDatabaseName()<<endl;

    // Prepare SQL query
    LPCTSTR query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";
    cout<<DAM<<": SQL query:\n  "<<query<<endl;
       
    // Run the query and create a record set
    CRecordset rs(&db); 
    result = rs.Open(CRecordset::dynaset, query, CRecordset::none);
    if (result == TRUE)
    {
        cout<<DAM<<": Retrieve schema info for the given result set: "<<endl;
        CODBCFieldInfo fInfo; 
        short sFieldCount = rs.GetODBCFieldCount();
        if (sFieldCount > 0)
        {
            for (short nIndex=0; nIndex < sFieldCount; nIndex++)
            {
                CODBCFieldInfo fInfo;
                rs.GetODBCFieldInfo(nIndex, fInfo);
                cout<<" | "<<fInfo.m_strName;
            }
            cout<<endl;
        }
        else
        {
            cout<<DAM<<": Error: Number of fields in the result set is 0."<<endl;
        }
    
        cout<<DAM<<": Fetch the actual data: "<<endl;
        CDBVariant var;
        CString value;
       
        // Loop through the rows in the result set
        int rowCount = 0;
        while (!rs.IsEOF())
        {
            for (short nIndex=0; nIndex < sFieldCount; nIndex++)
            {
                rs.GetFieldValue(nIndex, var);
                switch (var.m_dwType)
                {
                    case DBVT_STRING:
                        value.Format("%s", var.m_pstring->GetBuffer(var.m_pstring->GetLength()));
                        break;
                    case DBVT_ASTRING:
                        value.Format("%s", var.m_pstringA->GetBuffer(var.m_pstringA->GetLength()));
                        break;
                    case DBVT_WSTRING:
                        value.Format("%s", var.m_pstringW->GetBuffer(var.m_pstringW->GetLength()));
                        break;
                    default:
                        value = "";
                }
                cout<<" | "<<value;
            }
            cout<<endl;
            rowCount++;
            rs.MoveNext();
        }
        cout<<DAM<<": Total Row Count: "<<rowCount<<endl;
    }
}
CATCH_ALL(e)
{
    TCHAR  errMsg[255];
    e->GetErrorMessage(errMsg, 255);
    cout<<DAM<<": CException: "<<errMsg<<endl;
}
END_CATCH_ALL

db.Close();
cout<<DAM<<": Cleanup. Done."<<endl;

Пример использования JDBC-ODBC

JDBC представляет собой уровень доступа к данным, позволяющий коду на языке Java взаимодействовать с соответствующим источником данных. Мост JDBC-ODBC представляет собой реализацию драйвера базы данных, в котором для подключения к базе данных Access используется драйвер ODBC. Этот драйвер преобразует вызовы методов JDBC в вызовы функций ODBC.

private static String strConnect =
"jdbc:odbc:DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=C:\\Northwind.accdb;PWD=1L0v3Acce55;";

В приведенном ниже примере кода на Java извлекается схема и данные.

try {
   Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
   Connection con = DriverManager.getConnection(strConnect, "",""); 
   if (null == con) {
   System.out.println(DAM + "Unable to connect to data source " + strConnect);
   return;
   }
   
   System.out.println(DAM + ": Successfully connected to database. Data source name:\n  " 
+ con.getMetaData().getURL());
  
   // Prepare SQL query.
   String query = "SELECT Customers.[Company], Customers.[First Name] FROM Customers ORDER BY Customers.[Company] ASC;";
   System.out.println(DAM + ": SQL query:\n " + query);
   
   // Run the query and create a record set
   Statement stmt = con.createStatement();
   stmt.execute(query); 
   ResultSet rs = stmt.getResultSet(); 
   if (rs != null) {
   System.out.println(DAM + ": Retrieve schema info for the given result set: ");
   ResultSetMetaData rsmd = rs.getMetaData();
   for (int i=1; i <= rsmd.getColumnCount(); i++) {
   System.out.print(" | " + rsmd.getColumnName(i));
   }
   
   System.out.println("\n" + DAM + ": Fetch the actual data: ");
   int rowCount = 0;
   while (rs.next()) {
   for (int i=1; i <= rsmd.getColumnCount(); i++) {
       System.out.print(" | " + rs.getString(i));
       }
   System.out.println("");
   rowCount++;
       }
   System.out.println(DAM + ": Total Row Count: " + rowCount);
   }
   stmt.close(); 
   con.close(); 
} catch (Exception err) {
   System.out.println(DAM + ": Exception: " + err.getMessage());
} finally {
   System.out.println(DAM + ": Cleanup. Done.");
}

Данные о производительности

Данные о производительности были получены для 64-разрядной версии Access 2010, работающей в 64-разрядной операционной системе Windows Server 2008 с пакетом обновления 2 (SP2), которая была установлена на компьютере с двухъядерным процессором AMD 64 Athlon X2 4600+ с тактовой частотой 2,40 ГГц и 8 ГБ ОЗУ. В тестовых программах не выводились данные в пользовательский интерфейс и не использовались новые и расширенные возможности ядра ACE.

На рис. 3 приведена диаграмма с данными о производительности.

Рис. 3. Показатели производительности (в секундах)

Измерение производительности

Примечание

Все тестовые программы запускались в виде консольных приложений, за исключением кода VBA DAO, который запускался в среде VBA/VBE. Это означает, что код на VBA был единственной программой с привилегией выполнения в том же адресном пространстве, что и MSAccess.exe; это привело к значительному сокращению количества операций дискового ввода-вывода и ошибок страниц и, соответственно, к повышению общей производительности.

Использование 32- и 64-разрядных поставщиков ACE

Поставщики ACE (ACE DAO, ACE OLE DB и ACE ODBC) для Access 2007 доступны только в виде 32-разрядных версий. Поставщики ACE для Access 2010 доступны в виде 32- и 64-разрядных версий.

Всего возможно три конфигурации.

Полностью 64-разрядное решение (64-разрядная версия Access, 64-разрядная версия Windows)

Для реализации 64-разрядного решения необходимо выполнить указанные ниже действия.

  1. Развертывание 64-разрядной версии Access 2010 в 64-разрядной версии Windows

  2. Разработка собственного 64-разрядного решения для доступа к данным

Полностью 32-разрядное решение (32-разрядная версия Access, 32-разрядная версия Windows)

При наличии 32-разрядного приложения, которое должно работать с Access 2010 без изменений, необходимо установить 32-разрядную версию Access 2010.

32-разрядная версия Access 2010 работает точно так же, как 32-разрядная версия Access 2007, поэтому никаких изменений в код VBA, надстройки COM и элементы ActiveX вносить не требуется.

Решение на базе WOW64 (32-разрядная версия Access, 64-разрядная версия Windows)

Технология WOW64 позволяет выполнять 32-разрядные приложения на 64-разрядных платформах Windows. 32-разрядную версию Access 2010 можно установить в 64-разрядной версии Windows. В этом случае приложения для работы с данными также должны быть 32-разрядными, чтобы взаимодействовать с поставщиками ACE. Такая конфигурация используется для 64-разрядных операционных систем Windows по умолчанию и обеспечивает совместимость с 32-разрядными приложениями Office.

Хотя 32-разрядные приложения могут работать прозрачно, смешивание двух типов кода в одном процессе не поддерживается. 64-разрядное приложение не может подключаться к 32-разрядной системной библиотеке (DLL); аналогичным образом 32-разрядное приложение не может подключаться к 64-разрядной системной библиотеке.

Важно!

При попытке запустить устаревший 32-разрядный код в 64-разрядной версии Access возникнут ошибки времени выполнения. Например, из-за несоответствия версий пользовательского приложения(32-разрядный код) и одного из 64-разрядных поставщиков ACE, установленных с 64-разрядной версией Microsoft Access, может возникнуть ошибка "Поставщик Microsoft.ACE.OLEDB.12.0 не зарегистрирован на локальном компьютере". Чтобы устранить эту проблему, либо обновите пользовательский код до 64-разрядной версии, либо удалите 64-разрядную версию Access и установите 32-разрядную.

Рис. 4. Соответствие версий поставщиков ACE и приложений

Сравнение 32-разрядной и 64-разрядной версий

Параллельная установка

Для параллельной установки 64- и 32-разрядных выпусков Office 2010 поддержка не предоставляется. Это относится и к Access.

Другие вопросы

Перед развертыванием 64-разрядной версии Access определите, подходит ли такой вариант развертывания для конкретной среды. На совместимость с текущим 32-разрядным решением для Access влияет ряд факторов. Например, при использовании баз данных с удаленным исходным кодом (MDE-, ADE- и ACCDE-файлов) либо при использовании VBA-кода с операторами Declare, надстройками COM и элементами ActiveX необходимо приложить определенные усилия, чтобы эти функции заработали с 64-разрядной версией Access. Для устранения этой проблемы также можно установить 32-разрядную версию Access в 32-разрядной версии Windows либо 32-разрядную версию Access (WOW64) в 64-разрядной версии Windows. Дополнительные сведения по этому вопросу см. в статье, посвященной 64-разрядным выпускам Office 2010.

Факторы, влияющие на выбор технологии доступа к данным

При наличии решения, работающего с существующей базой данных Access, может потребоваться и дальше использовать задействованную в приложении технологию доступа к данным до тех пор, пока она удовлетворяет всем требованиям. В разделе Устаревшие методы доступа к данным перечислены драйверы, обеспечивающие возможность подключения к устаревшим форматам файлов Access. Помните, что все новые поставщики ACE также обеспечивают полную обратную совместимость.

Если приложение планируется использовать в течение длительного времени, то во время анализа требований и проектирования необходимо учитывать ряд факторов. Некоторые факторы, влияющие на принятие решения об использовании наиболее подходящего драйвера для доступа к данным, перечислены ниже.

  • Язык и платформа. Ограничены ли вы при реализации решения традиционными языками (C, C++, VBA) или управляемыми языками (C#, Visual Basic.NET)? Управляемые языки и лежащая в их основе платформа для доступа к данным (ADO.NET) обеспечивают более простую реализацию, более эффективное взаимодействие с платформой и масштабируемый доступ к данным. Например, если необходима тесная интеграция с .NET Framework, XML, решением, требующим использования разъединенной бизнес-логики (представления реляционных данных в памяти), или четко определенными, факторизованными интерфейсами с предсказуемым поведением, производительностью и семантикой, ADO.NET будет идеальным выбором. С другой стороны, если требуется максимально возможная производительность либо вы ограничены конкретным языком, имеет смысл рассмотреть и другие методы (непосредственное использование DAO, непосредственное использование OLE DB и т. д.). Если решение будет разрабатываться на языке C, единственным вариантом останется непосредственное использование ODBC. Аналогично при разработке на Java придется использовать драйвер JDBC-ODBC.

  • Функциональность. Если решение зависит только от баз данных Access, и в будущем ситуация не изменится, самым естественным вариантом будет выбор драйвера ACE DAO, поскольку он предоставляет наиболее полный набор функций. В конце концов, собственные технологии доступа к данным, как правило, позволяют сократить время разработки, упростить код и обеспечить более высокую производительность. Если будут использоваться расширенные возможности работы с наборами данных и подключения к вспомогательным внешним источникам, рассмотрите возможность использования ADO.NET (или ADO) либо OLE DB. Полную поддержку устаревших возможностей, таких как связанные таблицы и сохраненные запросы, а также новых сложных типов данных, появившихся в Access 2007, обеспечивает только драйвер ACE DAO. Драйвер ACE OLE DB обеспечивает ограниченную поддержку сложных данных. Например, для более эффективной поддержки сложного набора данных (для извлечения наборов записей в наборах данных) необходимо задать параметр подключения "JET OLE DB: Support Complex Data". Если этого не сделать, по умолчанию для сложных полей будут возвращаться списки разделенных значений. Технологии ADO.NET, ADO и ACE ODBC всегда возвращают для сложных полей списки разделенных значений.

  • Безопасность. Написание безопасного кода базы данных в многопользовательской и веб-среде — это намного более сложная задача, чем создание надежного пароля шифрования. Приложение, подключающееся к базе данных, может иметь множество потенциальных уязвимостей, которыми злоумышленник может воспользоваться для извлечения, изменения или уничтожения конфиденциальных данных. Таким образом, крайне важно понимать все аспекты безопасности, от моделирования угроз на этапе проектирования приложения до последующего развертывания и обслуживания приложения. В общем случае платформа .NET Framework обеспечивает более простую в использовании и тесно интегрированную среду, позволяющую повысить уровень безопасности приложения.

  • Производительность. Хотя технологии ADO.NET и ADO работают быстро, при работе с ядром ACE они формируют дополнительный уровень абстракции между приложением и поставщиком ACE OLE DB. В общем случае непосредственное использование DAO, OLE DB и ODBC обеспечивает максимальную скорость работы, особенно для больших баз данных. Если производительность недостаточна, а размер базы данных со временем должен существенно увеличиться, напишите приложение на C++ с использованием интерфейса OLE DB или DAO.

  • Обслуживание. Для разработки простых решений подходит ADO.NET или непосредственное использование DAO (а также, возможно, ADO), см. примечание. Выбор технологии доступа к данным OLE DB влияет на затраты на обслуживание приложения в долгосрочной перспективе. Технология OLE DB более затратна, чем DAO или ADO.NET, поскольку обслуживание и усовершенствование сложного кода COM является более трудной задачей. Вместо непосредственного использования OLE DB можно воспользоваться технологией ATL OLE DB (пример кода прилагается), которая эффективно абстрагирует сложность COM.

Примечание

Поставщики ACE в Office Access 2007 работают только с 32-разрядным клиентским кодом. Поставщики ACE в Access 2010 поддерживают 32-и 64-разрядный код. Для реализации 64-разрядного решения необходимо, чтобы и у вас, и у ваших клиентов была развернута 64-разрядная версия Access 2010.

Устаревшие методы доступа к данным

В таблице 2 перечислены устаревшие методы доступа к данным на момент выпуска Access 2007. Эти методы не поддерживаются для баз данных Access, сохраненных в формате ACCDB, и их следует использовать только для обслуживания устаревших приложений.

Таблица 2. Устаревшие методы доступа к данным

Имя поставщика

Метод доступа к данным

Подключение и другие сведения

Поддерживаемые языки

Поставщик OLE DB JET 4.0

OLE DB

Microsoft.JET.OLEDB.4.0

<Atldbcli.h>

C++

MFC DAO

MFC DAO

<Afxdao.h>;

Устанавливается с MDAC; классы MFC, начинающиеся с префикса CDao.

Классы MFC DAO позволяют воспользоваться устаревшим ядром СУБД Microsoft JET. Однако эти классы не поддерживаются в Access 2007. DAO 3.6 является окончательной версией этой технологии. Она недоступна в 64-разрядных версиях Windows. Мастера Visual C++ .NET не создают код для автоматического создания и открытия наборов записей.

C++

Драйвер Access ODBC 4.0

MFC ODBC

Driver={драйвер Microsoft Access (*.mdb)};DBQ=путь к MDB-файлу

<Afxdb.h>;

Odbcjt32.dll;

C++

Заключение

В данной технической статье описывается высокоуровневая архитектура Microsoft Access, ядро ACE и поставщики данных. Здесь рассматриваются различные технологии доступа к данным, доступные для программирования в Access, независимо от типа (машинный или управляемый) и разрядности (32 или 64 бита) разрабатываемого кода. С помощью таких технологий доступа к данным, как DAO, OLE DB, ADO.NET, ADO, ODBC и JDBC, можно создавать собственные решения на базе Access даже для самых сложных и нетривиальных задач. Как правило, драйвер ACE DAO, поставщик по умолчанию для ядра ACE, обеспечивает наиболее полнофункциональный собственный интерфейс для баз данных Access, а для языков .NET хорошей альтернативой является ADO.NET. Оба поставщика не только эффективно интегрируются с ядром ACE, но и обеспечивают быструю, стабильную и обратно совместимую среду с поддержкой устаревших форматов файлов.