次の方法で共有


データベース属性によるデータ アクセスの簡略化

このトピックでは、データベース属性を使用してデータベース操作を簡略化する方法について説明します。

データベースから情報にアクセスする基本的な方法は、データベース内の特定のテーブルに対して、コマンド (またはテーブル) クラスとユーザー レコード クラスを作成する方法です。 データベース属性を使用すると、以前は行う必要があったテンプレート宣言の一部を簡略化できます。

以下のセクションでは、データベース属性の使用方法を説明するために、2 つの同等のテーブル クラスとユーザー レコード クラスの宣言を示します。1 つ目では属性を使用し、2 つ目では OLE DB テンプレートを使用します。 このような宣言コードは、通常、テーブルまたはコマンド オブジェクトを表す名前のヘッダー ファイル (Authors.h など) に配置されます。

2 つのファイルを比較すると、属性を使用した方がいかに簡単かを確認できます。 違いは次のとおりです。

  • 属性を使用する場合、宣言する必要があるクラスは 1 つ、CAuthors のみです。テンプレートを使用する場合は、CAuthorsNoAttrAccessorCAuthorsNoAttr の 2 つを宣言する必要があります。

  • 属性バージョンでの db_source の呼び出しは、テンプレート宣言での OpenDataSource() の呼び出しと同じです。

  • 属性バージョンでの db_table の呼び出しは、次のテンプレート宣言と同じです。

    class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor>>
    
  • 属性バージョンでの db_column の呼び出しは、テンプレート宣言での列マップ (BEGIN_COLUMN_MAP ... END_COLUMN_MAP を参照) と同じです。

ユーザー レコード クラスの宣言は属性によって挿入されます。 ユーザー レコード クラスは、テンプレート宣言の CAuthorsNoAttrAccessor と同じになります。 テーブル クラスが CAuthors の場合、挿入されるユーザー レコード クラスの名前は CAuthorsAccessor となります。その宣言は、挿入されたコードでのみ確認できます。 詳しくは、「ユーザー レコード」の「属性が挿入されたユーザー レコード クラス」をご覧ください。

属性を使ったコードとテンプレートを使ったコードのどちらでも、CDBPropSet::AddProperty を使用して行セットのプロパティを設定する必要があります。

このトピックで説明している属性について詳しくは、「OLE DB コンシューマー属性」をご覧ください。

Note

下記の例をコンパイルするには、次の include ステートメントが必要です。

#include <atlbase.h>
#include <atlplus.h>
#include <atldbcli.h>

属性を使用したテーブルとアクセサーの宣言

次のコードでは、テーブル クラスで db_sourcedb_table を呼び出しています。 db_source は、使用するデータ ソースと接続を指定します。 db_table は、テーブル クラスを宣言するための適切なテンプレート コードを挿入します。 db_column は、列マップを指定し、アクセサー宣言を挿入します。 OLE DB コンシューマー属性は、ATL をサポートしている任意のプロジェクトで使用できます。

次に示すのは、属性を使用したテーブルとアクセサーの宣言です。

//////////////////////////////////////////////////////////////////////
// Table and accessor declaration using attributes
// authors.h
//////////////////////////////////////////////////////////////////////

// Table class declaration
// (Note that you must provide your own connection string for db_source.)
[
   db_source(L"your connection string"),
   db_table("Authors")
]
class CAuthors
{
public:
   DBSTATUS m_dwAuIDStatus;
   DBSTATUS m_dwAuthorStatus;
   DBSTATUS m_dwYearBornStatus;
   DBLENGTH m_dwAuIDLength;
   DBLENGTH m_dwAuthorLength;
   DBLENGTH m_dwYearBornLength;
   [db_column("1", status = "m_dwAuIDStatus", length = "m_dwAuIDLength")] LONG m_AuID;
   [db_column("2", status = "m_dwAuthorStatus", length = "m_dwAuthorLength")] TCHAR m_Author[51];
   [db_column("3", status = "m_dwYearBornStatus", length = "m_dwYearBornLength")] SHORT m_YearBorn;
   void GetRowsetProperties(CDBPropSet* pPropSet)
   {
      pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_IRowsetChange, true);
   }
};

テンプレートを使用したテーブルとアクセサーの宣言

次に示すのは、テンプレートを使用したテーブルとアクセサーの宣言です。

//////////////////////////////////////////////////////////////////////
// Table and user record class declaration using templates
// authors.h
//////////////////////////////////////////////////////////////////////

// User record class declaration
class CAuthorsNoAttrAccessor
{
public:
   DWORD m_dwAuIDStatus;
   DWORD m_dwAuthorStatus;
   DWORD m_dwYearBornStatus;
   DWORD m_dwAuIDLength;
   DWORD m_dwAuthorLength;
   DWORD m_dwYearBornLength;
   LONG m_AuID;
   TCHAR m_Author[51];
   SHORT m_YearBorn;
   void GetRowsetProperties(CDBPropSet* pPropSet)
   {
      pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true);
      pPropSet->AddProperty(DBPROP_IRowsetChange, true);
   }
   HRESULT OpenDataSource()
   {
      CDataSource _db;

HRESULT hr;
      hr = _db.OpenFromInitializationString(L"your connection string");
      if (FAILED(hr))
      {
#ifdef _DEBUG
         AtlTraceErrorRecords(hr);
#endif
         return hr;
      }
      return m_session.Open(_db);
   }
   void CloseDataSource()
   {
      m_session.Close();
   }
   operator const CSession&()
   {
      return m_session;
   }
   CSession m_session;
   BEGIN_COLUMN_MAP(CAuthorsNoAttrAccessor)
      COLUMN_ENTRY_LENGTH_STATUS(1, m_AuID, m_dwAuIDLength, m_dwAuIDStatus)
      COLUMN_ENTRY_LENGTH_STATUS(2, m_Author, m_dwAuthorLength, m_dwAuthorStatus)
      COLUMN_ENTRY_LENGTH_STATUS(3, m_YearBorn, m_dwYearBornLength, m_dwYearBornStatus)
   END_COLUMN_MAP()
};
class CAuthorsNoAttr : public CTable<CAccessor<CAuthorsNoAttrAccessor>>
{
public:
   HRESULT OpenAll()
   {
HRESULT hr;
      hr = OpenDataSource();
      if (FAILED(hr))
         return hr;
      __if_exists(GetRowsetProperties)
      {
         CDBPropSet propset(DBPROPSET_ROWSET);
         __if_exists(HasBookmark)
         {
            propset.AddProperty(DBPROP_IRowsetLocate, true);
         }
         GetRowsetProperties(&propset);
         return OpenRowset(&propset);
      }
      __if_not_exists(GetRowsetProperties)
      {
         __if_exists(HasBookmark)
         {
            CDBPropSet propset(DBPROPSET_ROWSET);
            propset.AddProperty(DBPROP_IRowsetLocate, true);
            return OpenRowset(&propset);
         }
      }
      return OpenRowset();
   }
   HRESULT OpenRowset(DBPROPSET *pPropSet = NULL)
   {
HRESULT hr = Open(m_session, "Authors", pPropSet);
#ifdef _DEBUG
      if(FAILED(hr))
         AtlTraceErrorRecords(hr);
#endif
      return hr;
   }
   void CloseAll()
   {
      Close();
      CloseDataSource();
   }
};

関連項目

OLE DB コンシューマー属性