Microsoft Access 2010 を使用したデータ プログラミング

Office 2010

概要: Microsoft Office Access 2007 または Microsoft Access 2010 でデータ アクセス用のネイティブ コード (C、C++、Java、VBA) やマネージ コード (C#、Visual Basic.NET) を作成する方法を説明します。また、Access のアーキテクチャ、ACE エンジンとデータ プロバイダー、32 ビットと 64 ビットのプラットフォームについて説明するほか、新規または以前のデータベース プロジェクトで最適なデータ アクセス テクノロジを選択する際の考慮事項も紹介します。

この技術記事では、Access 2007 および Access 2010 のデータ アクセスに関するプログラミング上の多くのポイントについて説明します。また、Microsoft Access データベース エンジン (ACE エンジン) と呼ばれる Access エンジンについても説明します。この記事は、Access データベース向けのデータ アクセス ソリューション開発時に利用できるオプションに関する詳細情報を求めているデータベース開発者のために書かれています。この記事のねらいは、ここで言及するあらゆるデータ アクセス インターフェイスに関する詳細を提供することではなく、ACE エンジン上で動作するように構築されたプログラミング モデルをより深く理解できるように、ACE エンジンのアーキテクチャの概要を示すことにあります。付属のサンプル コードは、ネイティブ言語 (C、C++、Java、および VBA) と .NET Framework 言語 (C# および Visual Basic.NET) の両方で記述されており、これらの言語のいくつかでプログラミング経験がなくても、すぐに作業を始められるようになっています。

この技術記事には、次のような質問に対する回答が記されています。

  • 以前の 32 ビット アプリケーションは Access の 64 ビット ソフトウェアとうまく連携できますか?

  • 一般に、プログラムによって Access データベースを操作する方法で最も高速なものは何ですか?

  • プログラミング言語の C (ANSI/ISO C) または Java を使用して ACE エンジンに接続する方法はありますか?

  • Microsoft Foundation Class (MFC) の以前のデータ アクセス オブジェクト (DAO) コードを使用して .accdb データベースを操作できますか?

コード例

この技術記事では、Microsoft Visual Studio 2008 を使用して作成され、ダウンロードできる完全なプログラムを 9 つ示します。

それぞれのコード例は、各種プログラミング言語とさまざまなデータ アクセス テクノロジ (DAO、OLE DB、ADO.NET、ADO、ODBC、JDBC など) を使用して同じデータ アクセス アルゴリズムを実行します。各プログラムのコンソール出力は、ほとんど同じです。コード例には、データベースを復号化するための強力なパスワードによる接続文字列の作成、暗号化されたデータベースへの接続、SQL クエリの作成と実行、スキーマとレコードセットの操作、並べ替え済みデータの取得など、データ アクセスに関する重要なプログラミング機能が示されています。

Access エンジンは Windows オペレーティング システムの一部ではないので、ACE エンジンとそのプロバイダーをローカル コンピューターにインストールする必要があります。詳細については、「ACE エンジンの入手先」を参照してください。

この技術記事では、コード例に含まれるすべてのデータ プロバイダーのパフォーマンス データも示します。

この技術記事の対象読者

データ アクセス テクノロジのテーマは幅広く、また、このガイドは、さまざまな開発者を対象にしているので、ビジネス ロジックまたはアプリケーションのレベルで Access データを操作するすべての開発者にとって有用です。ただし、この技術記事は、データベース プログラミング全般に関心がある IT 担当者、学生、愛好家が読者になることも想定して書かれています。

この記事では、読者が Visual Studio 環境や (構造化および .NET Framework) プログラミングの基礎についての知識を持ち、リレーショナル データベースと SQL の概念に習熟していることを前提としています。また、これまでにリリースされた任意の Microsoft Access でテーブルやクエリを問題なく作成できることも前提としています。

メモ メモ

このドキュメントに、特定のバージョンの Microsoft Access (Microsoft Access 2003 など) ではなく、単に Access と記されている場合、その情報は Microsoft Office Access 2007 と Microsoft Access 2010 の双方に適用されるものとします。

図 1 は、Access (UI) と ACE (エンジン) がどのようにして完全なデータベース管理システム (DBMS) を形成するのかを示しています。

図 1. Access 2010 の概念図

Access 2010 の高レベルな概念図

Access の UI が受け持つのは、ユーザー インターフェイスと、ユーザーがフォーム、レポート、クエリ、マクロ、ウィザードなどによってデータを表示、編集、および使用するすべての手段です。一方、Microsoft Access エンジン (ACE エンジン) は、次に示すようなコアとなるデータベース管理サービスを提供します。

  • データ ストレージ─ファイル システムにデータを格納します。

  • データ定義─テーブル、フィールドなど、データを保持するための構造を作成、編集、または削除します。

  • データ整合性─データの破壊を防ぐ関係性のルールを適用します。

  • データ操作─既存データの追加、編集、削除、または並べ替えを行います。

  • データ取得─SQL を使用してシステムからデータを取得します。

  • データ暗号化─許可されていない使用からデータを保護します。

  • データ共有─マルチユーザー ネットワーク環境でデータを共有します。

  • データ発行─クライアントまたはサーバー Web 環境で機能します。

  • データのインポート、エクスポート、およびリンク設定─各種ソースのデータを操作します。

データ アクセスの観点から見ると、Access は ACE エンジンをユーザーに視覚的に提示する手段といえます。

ACE エンジンの入手先

この技術記事に示すコード例を実行するには、ACE エンジンがコンピューター上に必要であり、以下に示す Access 2010 (または Office Access 2007) 製品のいずれかをインストールする必要があります。

メモ メモ

Microsoft Access データベース エンジン 2007 および 2010 ドライバーのリリースによって、ソリューション開発者は、ツールの構築や .accdb, .xlsx, .xlsb といった Office ファイルに対する読み取りと書き込みができるようになりました。また、ソリューション構築者は、(SQL のような) サーバーに Office をインストールしなくても Office ファイル形式の読み取りや書き込みをそうしたサーバー上で行えます。ただし、このドライバーをスタンドアロンのデータ ストアとして使用することは認められていません。

Microsoft JET エンジンについて

Access 2007 より前の Access では、Microsoft Joint Engine Technology (JET) エンジンを使用していました。JET は Access の一部として一般に認められていましたが、かつて JET エンジンは別の製品でした。Microsoft Windows 2000 のリリース以来、JET は Windows オペレーティング システムの一部となり、Microsoft Data Access Components (MDAC) によって配布または更新されるようになりました。しかし、Access 2007 のリリースによって、JET エンジンは非推奨となり、MDAC で配布されなくなりました。その代わりに、現在 Access では、統合および改良された ACE エンジンを使用しています。ACE エンジンは、元になった JET コード ベースのコード スナップショットをとることから開発が始まったものです。

ACE エンジンは、以前のバージョンの JET エンジンとの完全な下位互換性があるので、以前のバージョンの Access から (.mdb) ファイルを読み書きできます。このエンジンは現在 Access チームが所有しているため、開発者は、自らの Access ソリューションが将来も動作し続けることだけでなく、より高速で堅牢になり、機能が充実していくことにも確信を持てます。たとえば、Access 2010 のリリースで特に注目される改良点として、ACE エンジンのアップグレードによって 64 ビット版がサポートされ、SharePoint 関連テクノロジおよび Web サービス全般との統合が強化されたことが挙げられます。Microsoft は、開発者プラットフォームとしての Access に注力しています。

Microsoft は Access データベースの操作方法をいくつか提供しています。Access プログラミングでは、以下のデータ アクセス API とデータ アクセス層が使用されます。

  • データ アクセス オブジェクト (DAO)

  • Object Linking and Embedding, Database (OLE DB)

  • ADO.NET

  • ActiveX データ オブジェクト (ADO)

  • Open Database Connectivity (ODBC)

ACE エンジンは、上記の DAO、OLE DB、ODBC という 3 つのテクノロジのプロバイダーを実装したものです。ACE DAO プロバイダー、ACE OLE DB プロバイダー、および ACE ODBC プロバイダーは、Access 製品によって配布されます (ADO は例外で、依然として Microsoft Windows DAC の一部になっています)。ADO および ADO.NET を含む、データ アクセスに関する他の多くのプログラミング インターフェイス、プロバイダー、およびシステムレベル フレームワークは、これら 3 つの ACE プロバイダーを基にして構築されています。図 2 は、Access コンポーネントの概要を示したダイアグラムです。

図 2. データ アクセス プログラミング環境における ACE エンジンのアーキテクチャ

ACE のアーキテクチャ図

次の表は、この技術記事で説明するデータ アクセス方法をまとめたものです。

表 1. データ アクセス方法

プロバイダー名

データ アクセス方法

接続情報

サポートされる言語

ACE DAO

Direct DAO の例

Acedao.tlh (acedao.dll から生成)

acedao.dll

C++

VBA DAO の例

Set db = CurrentDb()

VBE 環境で動作

VBA

ACE OLE DB

ATL OLE DB の例

Microsoft.ACE.OLEDB.12.0

<Atldbcli.h> および <Atldbsch.h>; Aceoledb.dll

C++

ADO.NET

C# による ADO.NET の例

Microsoft.ACE.OLEDB.12.0

using System.Data.OleDb;

C#

Visual Basic.NET による ADO.NET の例

Visual Basic.NET による ADO.NET の例

Microsoft.ACE.OLEDB.12.0

Imports System.Data.OleDb

Imports System.Console

Visual Basic.NET

ADO

ADO の例

Msado15.tlh (Msado15.dll から生成);

MDAC 2.8 または Windows DAC 6.0 によってインストール

C++

ACE ODBC

Direct ODBC の例

Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=mdb/accdb ファイルのパス

<Sqlext.h>;

Aceodbc.dll;

C/C++

MFC ODBC の例

Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=mdb/accdb ファイルのパス

<Afxdb.h>;

Aceodbc.dll;

C++

JDBC-ODBC の例

jdbc:odbc:DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=mdb/accdb ファイルのパス

Java

Access 2007 のリリースによって非推奨となったデータ アクセス方法の詳細と一覧については、「非推奨のデータ アクセス方法」を参照してください。

DAO

当初、DAO は Access 開発者向けの排他的なデータ アクセス方法でした。

Direct DAO の例

このアクセス方法は、ACE エンジンのほとんどの機能を公開しているため、Access 2007 で導入された新機能に対する最善のサポートを提供します。Direct DAO では Acedao.dll を使用します。このコードをコンパイルする場合は、#import マクロを使用して .tlh ヘッダーを生成します。そのためには、次のコード例に示すようなディレクティブを指定します。

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

32 ビットと 64 ビットのどちらのオペレーティング システムでコードをコンパイルするかによって、このパスの "(x86)" という部分の削除が必要になる場合があります。その要否を確認する方法の 1 つは、次に示すレジストリ パスのいずれかの下にある 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.

VBA DAO の例

以下のコード例は、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 によるシステムレベルのデータ アクセス用プログラミング インターフェイスです。これは、仕様であり、一連のコンポーネントやファイルではありません。また、ADO の基になるテクノロジであり、ADO.NET にとってはデータのソースとなります。OLE DB は、コンシューマーに提供されるさまざまなデータベース管理システム サービスをカプセル化する一連の COM インターフェイスを指定します。OLE DB は、Access データベースを含むあらゆる種類のデータにアクセスするためのオープン スタンダードです。OLE DB は、リレーショナル データベースをはじめとするストア内のデータへのライブ接続を使用することで、フロントエンドのデータベース クライアントと中間層のビジネス オブジェクトを含む開発要件をサポートします。

ATL OLE DB の例

この例では、Active Template Library (ATL) を使用するために <Atldbcli.h> と <Atldbsch.h>をインクルードしています。接続情報では、Aceoledb.dll で実装された Microsoft.ACE.OLEDB.12.0 データ プロバイダーを使用しています。

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 マネージ プロバイダーを使用し, .NET マネージ プロバイダーは OLE DB や ODBC といった基になる API を使用します。この技術記事では、ADO.NET の例を 2 つ (C# と Visual Basic.NET) 示します。どちらの例でも、基になる OLE DB をデータ アクセス層として使用しています。

C# による ADO.NET の例

以下は、C# による ADO.NET のコード例です。

// 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);
}

Visual Basic.NET による ADO.NET の例

以下は、Visual Basic.NET による ADO.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 データ オブジェクト (ADO) は、COM ベースでアプリケーション レベルのインターフェイスを OLE DB データ プロバイダーに提供します。OLE DB への直接コーディングに比べるとパフォーマンスは低下しますが、ADO は簡単に習得して使用できます。C++ プログラマは、ADO を使用して、基になる OLE DB インターフェイスにアクセスできます。通常、ほとんどの開発者は、メモリ リソース管理や、OLE DB がデータ アクセス処理を任せているコンポーネントの手動集計といった低レベルの制御には関心がありません。

単一のデータベース エンジンの機能を公開していた DAO とは異なり、ADO は一般的なプログラミング モデルを使用してデータへの普遍的なアクセスを行います。

ADO の例

ADO では、MDAC 2.8 以降に含まれる Msado15.dll というライブラリを使用します。このコードをコンパイルするには、次のコード例に示すようなディレクティブを指定して .tlh ヘッダーを生成する #import マクロを使用する必要があります。

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

接続情報には、Aceoledb.dll で実装された Microsoft.ACE.OLEDB.12.0 データ プロバイダーを使用します。

_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 による現行のデータ アクセス テクノロジとしては、最も古いものです。そのメソッドは、従来の非オブジェクト指向の C ライクな API で公開されています。

Direct ODBC の例

このデータ アクセス方法は、既存アプリケーションをメンテナンスする場合や ANSI/ISO C を使用した作業が求められる場合にのみ推奨されます。次のコード例は、Aceodbc.dll ライブラリに実装されたドライバー {Microsoft Access Driver (*.mdb, *.accdb)} を <Sqlext.h> のインクルードによって使用する、Direct ODBC 用の接続情報を示しています。

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);

MFC ODBC の例

次のコード例は、Aceodbc.dll ライブラリに実装されたドライバー {Microsoft Access Driver (*.mdb, *.accdb)} を <Afxdb.h> のインクルードによって使用する、MFC ODBC 用の接続情報を示しています。

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 ブリッジは、ODBC ドライバーを利用して Access データベースに接続するデータベース ドライバーを実装したものです。このドライバーは、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.");
}

パフォーマンス結果は、2.40 GHz の AMD 64 Athlon X2 デュアル コア プロセッサ 4600+ CPU と 8 GB の RAM を使用して Windows Server 2008 SP2 を実行している 64 ビット オペレーティング システム上の 64 ビット Access 2010 で生成されました。ベンチマーク プログラムでは、ユーザー インターフェイス (UI) への出力は行わず、ACE エンジンの新機能や高度な機能も使用しませんでした。

図 3 は、パフォーマンス データを示すグラフです。

図 3. パフォーマンス測定結果 (単位: 秒)

パフォーマンスの測定
メモ メモ

VBA による DAO コードを除くすべてのベンチマーク プログラムはコンソール アプリケーションとして実行され、VBA による DAO コードは VBA/VBE 環境から実行されました。つまり、ディスク I/O 操作とページ フォールトの大幅な削減によって全体的なパフォーマンスの向上につながる、MSAccess.exe と同じアドレス空間内での実行の権限を持っていたプログラムは、VBA コードのみでした。

Access 2007 製品の ACE プロバイダー (ACE DAO、ACE OLE DB、または ACE ODBC) は 32 ビット環境でのみ利用できます。Access 2010 製品の ACE プロバイダーは 32 ビットと 64 ビットの両方のエディションで利用できます。

現在、基本的に 3 とおりの構成をとることができます。

64 ビットのみのソリューション (64 ビット Access、64 ビット Windows)

64 ビットのソリューションを実装するには、次の作業が必要です。

  1. 64 ビット Windows 上での 64 ビット Access 2010 の展開

  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 で実行することもできます。その場合、データ アプリケーションは ACE プロバイダーへの通信が可能な 32 ビットのものである必要があります。このテクノロジは、64 ビット Windows オペレーティング システムでの既定のインストールであり、32 ビット Office アプリケーションとの互換性を実現します。

32 ビット アプリケーションは透過的に実行できますが、同じプロセス内での 2 種類のコードの混在はサポートされていません。64 ビット アプリケーションは 32 ビットのシステム ライブラリ (DLL) に対してリンクを設定できず、同様に 32 ビット アプリケーションは 64 ビットのシステム ライブラリに対してリンクを設定できません。

重要なメモ 重要

以前の 32 ビット コードを 64 ビット Access に対して実行しようとすると、実行時エラーが発生します。たとえば、アプリケーション (32 ビット コード) と、64 ビット Microsoft Access によってインストールされた 64 ビットの ACE プロバイダーの 1 つとの間のバージョンの不一致によって "'Microsoft.ACE.OLEDB.12.0' プロバイダーはローカルのコンピューターに登録されていません" というエラーが発生する場合があります。この問題を解決するには、カスタム コードを 64 ビット版にアップグレードするか、64 ビット Access をアンインストールして 32 ビット Access に置き換えます。

図 4. ACE プロバイダーとアプリケーションとの間のバージョンのマッチング

32 ビット と 64 ビットの比較

並行インストール

Office 2010 の 64 ビット版と 32 ビット版の並行インストールは、一切サポートされていません。これは Access についても同様です。

その他の考慮事項

64 ビット Access を展開する前に、現在使用している特定の環境にとってそれが適切な展開オプションであるかどうかを判断してください。現在の 32 ビット Access ソリューションとの互換性に影響する可能性のある領域がいくつかあります。たとえば、ソース コード (.mde, .ade, .accde など) が削除されたデータベースを使用している場合や、Declare ステートメント、COM アドイン、または ActiveX コントロールを持つ VBA コードを使用している場合は、こうした機能を 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 の選択が最善といえます。一方、考えられる最高のパフォーマンスを求めている場合や、使用できる言語が特定のものに制限されている場合は、他の方法 (Direct DAO、Direct OLE DB など) も検討します。ただし、C 言語でソリューションを開発する場合は、選択肢が Direct ODBC に制限されます。同様に、Java による開発では JDBC-ODBC ドライバーを使用する必要があります。

  • 機能 ソリューションが Access データベースのみに依存し、そうした状況が今後も続く場合は、最も幅広い機能を提供している ACE DAO ドライバーの選択が妥当です。長期的に見ると、一般的にネイティブのデータ アクセス テクノロジは、開発時間の短縮、コードの簡素化、パフォーマンスの向上につながります。高度なレコードセット操作機能が必要で、サポート可能な外部ソースに接続する場合は、ADO.NET (または ADO) あるいは OLE DB の使用を検討します。また、ACE DAO ドライバーだけが、テーブルのリンクやクエリの保存といった以前の機能と Access 2007 で導入された複雑な新しいデータ型を完全にサポートしています。ACE OLE DB ドライバーには、複雑なデータのサポートに制限があります。たとえば、(レコードセット内のレコードセットを取得するために) 複雑なデータセットのサポート性を向上させるには、"JET OLE DB: Support Complex Data" という接続パラメーターを設定します。そうしないと、既定の状態では複雑なフィールドの区切りリストしか取得できません。ADO.NET、ADO、および ACE ODBC は、常に複雑なフィールドの区切りリストを取得します。

  • セキュリティ マルチユーザーの Web 環境でセキュリティ保護されたデータベース コードを記述することは、強力な暗号化パスワードの作成よりもずっと重要です。データベースにアクセスするアプリケーションには、攻撃者が悪用して機密データを取得、操作、または破壊できる潜在的な障害点が数多くあります。そのため、アプリケーションの設計フェーズでの脅威モデリングから最終的な展開と持続的なメンテナンスに至るまで、セキュリティのすべての側面を理解することが重要です。一般に, .NET Framework はアプリケーションのセキュリティ向上に関して使いやすく十分に統合された環境を提供します。

  • パフォーマンス ADO.NET と ADO は、高速ですが、ACE エンジンとの連携時にアプリケーションと ACE OLE DB プロバイダーとの間に追加の抽象レイヤーを挿入します。一般に、Direct DAO、OLE DB、および ODBC の各方法は、特にデータベースが大規模な場合に高速です。パフォーマンスが問題になっていて、時間の経過と共にデータベースの大幅な増大が予想される場合は、OLE DB または DAO インターフェイスを使用して C++ 言語でアプリケーションを記述できます。

  • メンテナンス 簡素なソリューションを開発するには、ADO.NET または Direct DAO (場合によっては ADO) が適しています。詳細についてはコメントを参照してください。OLE DB データ アクセス テクノロジの選択は、アプリケーションの長期的なメンテナンスのコストに影響を及ぼします。OLE DB が DAO や ADO.NET よりも高コストなのは、複雑な COM コードのメンテナンスと改良が困難になるためです。Direct OLE DB の代替案として、ATL OLE DB の方法を使用できます (サンプル ソースあり)。この方法では、基になる COM の複雑さがうまく抽象化されます。

メモ メモ

Office Access 2007 の ACE プロバイダーは 32 ビットのクライアント コードでのみ動作します。Access 2010 の ACE プロバイダーは 32 ビットと 64 ビットの両方のコードをサポートしています。64 ビットのソリューションを実装するには、開発側とクライアント側の双方が 64 ビットの Access 2010 製品を展開する必要があります。

表 2 に、Access 2007 の時点で非推奨になったデータ アクセス方法の一覧を示します。これらの方法は .accdb ファイル形式で保存された Access データベースでの使用がサポートされておらず、レガシ アプリケーションのメンテナンスのためだけに使用する必要があります。

表 2. 非推奨のデータ アクセス方法

プロバイダー名

データ アクセス方法

接続などに関する情報

サポートされる言語

JET4.0 OLE DB プロバイダー

OLE DB

Microsoft.JET.OLEDB.4.0

<Atldbcli.h>

C++

MFC DAO

MFC DAO

<Afxdao.h>;

MDAC によってインストールされます。CDao というプレフィックスを持つ MFC クラスです。

MFC DAO クラスにより、ユーザーは以前の Microsoft JET データベース エンジンを使用できます。ただし、これらは Access 2007 ではサポートされません。DAO 3.6 がこのテクノロジの最終バージョンです。これは 64 ビット Windows で利用できません。Visual C++ .NET ウィザードは、レコードセットの作成とオープンを自動的に行うコードを生成しません。

C++

Access ODBC ドライバー 4.0

MFC ODBC

Driver={Microsoft Access Driver (*.mdb)};DBQ=mdb ファイルのパス

<Afxdb.h>;

Odbcjt32.dll;

C++

この技術記事では、Microsoft Access のアーキテクチャの概要を示し、その ACE エンジンとデータ プロバイダーについて説明しました。また、ネイティブ コードとマネージ コード、32 ビットと 64 ビットのどちらで開発するかに関係なく、Access のプログラミングで自由に利用できるさまざまなデータ アクセス テクノロジについて説明しました。DAO、OLE DB、ADO.NET、ADO、ODBC、JDBC といったデータ アクセス テクノロジを使用すると、非常に複雑で要求の厳しいシナリオでもカスタムの Access ソリューションを作成し続けることができます。通常は、ACE エンジンの既定のプロバイダーとして ACE DAO ドライバーが Access データベースに対する最も幅広いネイティブ インターフェイスを提供し, .NET 言語向けには ADO.NET が優れた代替案になります。両者は ACE エンジンと十分に統合されているだけでなく、以前のファイル形式との下位互換性のある高速かつ安定した環境を提供します。

表示: