テクニカル ノート 53: DAO データベース クラス用カスタム DFX ルーチン
[!メモ]
Visual C++ .NET では、Visual C++ 開発環境およびウィザードでは DAO はサポートされなくなりました (DAO クラスは含まれているので、このクラスを使うことはできます)。Microsoft は、新しいプロジェクトに OLE DB テンプレート か ODBC と MFC を使用することをお勧めします。DAO は、既存のアプリケーションを保守するためだけに使用してください。
このテクニカル ノートは DAO レコード フィールド エクスチェンジ (DFX)の機能について説明します。なっていると DFX のルーチンでを理解するために、 DFX_Text 関数は、例として詳しく説明します。このテクニカル ノートへの追加情報源として、ユーザーの DFX の関数他のコードを確認できます。カスタム RFX)ルーチンを場合ほど多くの場合、カスタム DFX のルーチンを頻繁に必要ではありません (ODBC データベース クラスで使用される)必要とします。
このテクニカル ノートは含まれています:
DFX の概要
DAO レコード フィールド エクスチェンジと動的バインディングを使用して例
DFX のしくみ
カスタム DFX ルーチンの機能
DFX_Text の詳細
DFX の概要
CDaoRecordset のクラスを使用すると DAO レコード フィールド エクスチェンジの機能 (DFX)がデータを取得し、更新する手順を簡素化するために使用されます。プロセスは CDaoRecordset クラスのデータ メンバーの使用を簡略化されます。CDaoRecordsetから派生することで、テーブルまたはクエリの各フィールドを表す派生クラスにデータ メンバーを追加できます。この静的な束縛 「」の機能は簡単ですが、これは、すべてのアプリケーションの対象のデータのフェッチまたは更新メソッドでない場合があります。DFX は、現在のレコードが変更されるたびに、バインドされたフィールドを取得します。通貨が変更されると、フィールドのフェッチを必要としないパフォーマンス センシティブなアプリケーションを開発する場合、 CDaoRecordset::GetFieldValue に、 「動的バインディング」と CDaoRecordset::SetFieldValue は、データ アクセスの選択メソッドである場合があります。
[!メモ]
DFX と動的バインディングは相互に排他的ではないので、静的および動的バインディングのハイブリッド使用を使用できます。
例 1 - DAO レコード フィールド エクスチェンジのみの使用
( CDaoRecordset —開いている派生クラス CMySet )を既に仮定します)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
例 2 —動的バインディングだけの使用
( CDaoRecordset のクラス、 rsを使用していて、既に開いています)
// Add a new record to the customers table
COleVariant varFieldValue1 ( _T("MSFT"), VT_BSTRT );
//Note: VT_BSTRT flags string type as ANSI, instead of UNICODE default
COleVariant varFieldValue2 (_T("Microsoft"), VT_BSTRT );
rs.AddNew();
rs.SetFieldValue(_T("Customer_ID"), varFieldValue1);
rs.SetFieldValue(_T("Customer_Name"), varFieldValue2);
rs.Update();
例 3 - DAO レコード フィールド エクスチェンジと動的バインディングの使用
( CDaoRecordsetの従業員データの派生クラス empを参照するとします)
// Get the employee's data so that it can be displayed
emp.MoveNext();
// If user wants to see employee's photograph,
// fetch it
COleVariant varPhoto;
if (bSeePicture)
emp.GetFieldValue(_T("photo"), varPhoto);
// Display the data
PopUpEmployeeData(emp.m_strFirstName,
emp.m_strLastName, varPhoto);
DFX のしくみ
DFX の機能は、 MFC ODBC クラスによって使用されるレコード フィールド エクスチェンジ (RFX)の機能と同様に動作します。RFX と DFX の原則は同じですが、多くの内部違いがあります。DFX の関数のデザインは事実上すべてのコードがユーザー DFX のルーチンによって共有されるようにいません。最上位 DFX で各種の情報のみをします。
DFX は、 SQL の 選択 の句と SQL の パラメーター の句を必要に応じて構築します。
DFX は DAO GetRows の関数 (の後にこれ以上)で使用される結合の構造を構築します。
DFX (ダブルバッファリングが使用されている場合)、ダーティ フィールドを検出するために使用するデータ バッファーを管理します
DFX は、更新の NULL と DIRTY の状態の配列と設定値を必要に応じて管理します。
DFX の機能の中核は CDaoRecordset の派生クラスの DoFieldExchange 関数です。この関数は、適切な操作の種類のユーザー DFX の関数呼び出しをディスパッチします。DoFieldExchange を内部 MFC 関数を呼び出す前に操作の型を設定します。次の一覧は、さまざまな操作の型と簡単な説明を示します。
演算 |
Description |
---|---|
AddToParameterList |
ビルド パラメーター句 |
AddToSelectList |
ビルドは句を選択します |
BindField |
バインディングの構造を設定します |
BindParam |
パラメーター値を設定します |
フィックスアップ |
設定の空白の状態 |
AllocCache |
ダーティなチェックのキャッシュを割り当てます。 |
StoreField |
現在のレコードをキャッシュするように保存します |
LoadField |
取り消しはメンバー値にキャッシュします |
FreeCache |
無料のキャッシュ |
SetFieldNull |
フィールド ステータスと値を null に設定します |
MarkForAddNew |
ダーティなフィールドをモック null マークします。 |
MarkForEdit |
キャッシュにと一致していないダーティなフィールドをマークします |
SetDirtyField |
フィールドの値をダーティとしてマークされて設定します |
次のセクションでは、各操作には DFX_Textについて詳しく説明します。
DAO レコード フィールド エクスチェンジのプロセスを理解するうえで最も重要な機能は CDaoRecordset のオブジェクトの GetRows の関数を使用することです。DAO GetRows 関数は、いくつかの方法があります。このテクニカル ノートは簡単にこのテクニカル ノートのスコープ外にある場合にのみ GetRows について説明します。
DAO GetRows は、いくつかの方法があります。
は、データの複数のレコードと複数のフィールドを一度に取得できます。これは、大規模なデータ構造を処理すること、および各フィールドに対する適切なオフセットで、のより高速なデータ アクセスと構造体のデータの各レコードができます。MFC は、この機能をフェッチ複数のレコードを使用しません。
GetRows が作業できるもう一つの方法は 1 種類のデータ レコードの各フィールドを使用したデータの連結アドレスを指定することをプログラムにすることです。
DAO は呼び出し元に可変長の列の 「呼び出し元がメモリを割り当てるようにするには」をたどってします。この 2 番目の機能に CDaoRecordset のクラス (派生クラス)のメンバーにデータのコピーの数を最小限に抑える、データを直接ストレージを使用する利点があります。この 2 番目の機能は CDaoRecordset の派生クラスのデータ メンバーにバインドするメソッドの MFC の使用です。
カスタム DFX ルーチンの機能
これは、 DFX の関数で実行される正常に GetRowsをダイヤルする場合に最も重要な操作が必要なデータ構造を設定する機能である必要があります。この理由から明確です。他の多数の操作 DFX の関数もサポートする必要があること GetRows の呼び出しで正しく準備することが重要で複雑なまったく同じです。
DFX の使用はオンライン ドキュメントに記述されています。基本的に、 2 種類の要件があります。最初に、メンバーは、バインドされたフィールドおよびパラメーターの CDaoRecordset の派生クラスに追加する必要があります。この CDaoRecordset::DoFieldExchange の後でオーバーライドする必要があります。メンバーのデータ型が重要であることに注意してください。これは、データベースのフィールドのデータに一致するか、少なくともその型に変換できる必要があります。たとえば、データベースの数値フィールドは、長整数 CString のメンバーにショートメッセージを送信し、外接する場合は、常に変換できるデータベースのテキスト フィールドは長整数のメンバーへの長整数および境界などの数値表記によって、変換されない場合があります。(MFC)ではなく、 DAO および Microsoft Jet データベース エンジンは、変換を行います。
DFX_Text の詳細
前に述べた DFX 作業が例で使用する方法を説明する最適な方法。このため DFX_Text の internals に移動と、 DFX の少なくとも基本的な知識を提供するために、適した必要があります。
AddToParameterList
この操作は、 Jet に必要な SQL の パラメーター の句 (「Parameters <param name>, <param type> ... ;」)をビルドします。各パラメーターは、という名前の入力されます (RFX の呼び出しで指定された)。個々の型の名前を確認するために関数の CDaoFieldExchange::AppendParamType 関数を参照してください。DFX_Textの場合、使用される型は textです。AddToSelectList
SQL の 選択 の句をビルドします。これは、 DFX の呼び出しで指定された項目の名前がさらに追加されるため、非常に単純です (「SELECT <column name>, ...」)。BindField
操作の最も複雑です。前に述べたように、これ GetRows で使用する構造体をバインドする DAO を設定した場所です。DFX_Text のコードからわかるように、構造体の情報の種類は DAO の型を使用して格納されます ( DFX_Textの場合はDAO_CHAR か DAO_WCHAR )。また、使用されるバインディングの種類はセットアップされます。前のセクションでは GetRows は簡単にのみ説明していますが、 MFC で使用するバインディングの種類が直接アドレス バインディング ()DAOBINDING_DIRECT常にであることを示すだけで十分です。また、可変長の列のバインディング ( DFX_Textなど)はコールバックのバインディングに MFC でメモリの割り当てを制御し、正しい期間のアドレスを指定するために使用されます。これがデータを配置するための意味は、 MFC DAO を 「常に指定できます。また」、に直接メンバー変数へのバインディングを許可します。結合の構造体の他には、列バインディングのメモリ割り当てのコールバック関数と型のアドレスなどの要素が格納されます (項目の名前によってバインドする)。BindParam
このメンバーは、パラメーターで指定されたパラメーター値を持つ SetParamValue をダイヤルする単純な操作です。Fixup
各フィールドの NULL の状態を入力します。SetFieldNull
この操作は NULL としてのみ各フィールド ステータスを表示し、 PSEUDO_NULLにメンバー変数の値を設定します。SetDirtyField
各フィールドに指定されたダーティの SetFieldValue を呼び出します。
のそのほかすべての操作は、データ キャッシュの使用のみを処理されます。データ キャッシュは特定の処理をより簡単にするために使用される現在のレコードのデータの追加のバッファーです。たとえば、 「未」フィールドが自動的に検出できます。オンライン ドキュメントに説明されているように、完全に、フィールド レベルでオフにできます。バッファーの実装はマップを使用します。このマッピングは 「バインド」フィールド使用されます (または CDaoRecordset によって取得したデータ メンバーのアドレスに)データを動的に割り当てられたコピーを対応するために使用されます。
AllocCache
動的にキャッシュ フィールドの値を割り当て、マップに追加します。FreeCache
キャッシュ フィールドの値を削除し、マップから削除します。StoreField
データ キャッシュに現在のフィールドの値をコピーします。LoadField
フィールド メンバーにキャッシュされた値をコピーします。MarkForAddNew
現在のフィールドの値が非NULL および必要に応じてマーク、ダーティかどうかを確認します。MarkForEdit
データ キャッシュとダーティの現在のフィールドの値とマークを必要に応じて比較します。
ヒント |
---|
標準データ型の既存の DFX ルーチンのカスタム DFX のルーチンをシミュレートします。 |