テクニカル ノート 45: MFC/データベースの Long Varchar/Varbinary 型のサポート
[!メモ]
次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。
ここでは、 MFC データベース クラスを使用して ODBC SQL_LONGVARCHAR と SQL_LONGVARBINARY のデータ型を検索し送信する方法について説明します。
長い Varchar/Varbinary サポートの概要
ODBC SQL_LONG_VARCHAR と SQL_LONGBINARY のデータ型は、 (long データ列がここに呼ばれます)莫大な量のデータを保持できます。このデータを処理できる 3 種類の方法があります:
CString/CByteArrayにバインドします。
CLongBinaryにバインドします。
これをまったくバインドせず、長いデータ値を、データベース クラスに依存しない手動で検索して、生存にします。
3 個の各メソッドに長所と短所があります。
長いデータ列をクエリにパラメーターではサポートされません。これらは outputColumns でのみサポートされます。
CString/CByteArray に長いデータ列をバインドできます。
Sun:
この方法は理解しやすく使い慣れたクラスを使用します。フレームワークは DDX_Textを CString に CFormView サポートします。CString と CByteArray のクラスとの汎用文字列またはコレクションの機能の多くがあり、データ値を保持するために割り当てられたメモリの量をローカルに制御できます。フレームワークは 編集 か AddNew の関数呼び出しにデータ フィールドの古いコピーを保持し、フレームワークは自動的に、のデータへの変更を検出できます。
[!メモ]
CString が文字データで実行、バイナリ データで実行の CByteArray 用に設計されているため、 CStringに文字データ (SQL_LONGVARCHAR)を処理する、バイナリ データ ()SQL_LONGVARBINARYお勧めします。がに CByteArray。
CString と CByteArray に対する RFX 関数にデータ列の取得した値を保持するために割り当てられたメモリの既定のサイズをオーバーライドできるそのほかの引数があります。次の関数宣言の nMaxLength の引数に注意してください。:
void AFXAPI RFX_Text(CFieldExchange* pFX, const char *szName,
CString& value, int nMaxLength = 255, int nColumnType =
SQL_VARCHAR);
void AFXAPI RFX_Binary(CFieldExchange* pFX, const char *szName,
CByteArray& value,int nMaxLength = 255);
CString か CByteArrayに長いデータ列を取得する場合は、返されるデータの量最大は、既定では 255 バイトです。さらに何も無視されます。この場合、フレームワークは AFX_SQL_ERROR_DATA_TRUNCATED例外をスローします。しかし、 MAXINTまでから順番に明示的に nMaxLength、を向上させることができます。
[!メモ]
MFC で nMaxLength の値が SQLBindColumn の関数のローカル バッファーを設定するために使用されます。これは、データの格納用のローカル バッファーで、 ODBC ドライバーによって実際に返されるデータの量に影響しません。RFX_Text と RFX_Binary は SQLFetch のみを使用してバックエンド データベースからデータを取得するための 1 種類の呼び出しを行います。各 ODBC ドライバーについては単一のフェッチで返すことができるデータの量の別の制限があります。この制限は AFX_SQL_ERROR_DATA_TRUNCATED 例外がスローされた場合 nMaxLength の値が設定よりも小さい場合があります。このような状況では、すべてのデータが取得できるように、 RFX_Text または RFX_Binary の代わりに RFX_LongBinary の使用に切り替えます。
ClassWizard は CStringに SQL_LONGVARCHAR するか、の CByteArray に SQL_LONGVARBINARY をバインドします。、長いデータ列を取得する 255 以上のバイト割り当てを場合は、を nMaxLength の明示的な値を指定できます。
SQL_VARCHAR か SQL_VARBINARYにバインドされると長いデータ列がワーク フィールドを更新する CString か CByteArrayに同じにバインドされます。編集中に、データ値はデータ値の変更を検出し、列をダーティな、 null 値を適切に設定する 更新する が呼び出されると、キャッシュ後で比較されます。
CLongBinary に長いデータ列をバインドできます。
長いデータ列がデータの MAXINT のバイトを含める場合に、 CLongBinaryにそれを取得することを検討する必要があります。
Sun:
これは、使用できるメモリの容量まで全体の長いデータ列を取得します。
:短所
データをメモリに保持されます。この方法は、大量のデータに非常に、非常に高くなっています。フィールドが 更新する 操作に含まれていることを確認するために連結されたデータ メンバーの SetFieldDirty をダイヤルします。
CLongBinaryに長いデータ列を取得する場合は、データベース クラスは長いデータ列の合計サイズを確認し、それを保持するのに十分な大きさが HGLOBAL のメモリ セグメントを全体の値を割り当てます。データベース クラスは、割り当てられた HGLOBALに、全体のデータ値を取得します。
データ ソースが長いデータ列の予想サイズを返すことができない場合、フレームワークは AFX_SQL_ERROR_SQL_NO_TOTAL例外をスローします。HGLOBAL の割り当てに失敗すると、既定のメモリ不足例外がスローされます。
ClassWizard、の CLongBinary に SQL_LONGVARCHAR か SQL_LONGVARBINARY をバインドします。追加のメンバー変数ダイアログの変数の型として選択 CLongBinary 。ClassWizard は DoFieldExchange の呼び出しに、 RFX_LongBinary の呼び出しを追加し、バインドされたフィールドの合計数をインクリメントします。
CLongBinaryことを m_hData のメンバーの ::GlobalSize を呼び出して、新しいデータを保持するには、割り当てられた HGLOBAL が十分に大きいことが長いデータ列値を更新するには、最初に確認します。これが非常に小さかったら、 HGLOBAL を解放し、 1 を適切なサイズにしてください。新しいサイズを反映して設定された m_dwDataLength 。
それ以外 m_dwDataLength が、置換するデータのサイズを超える場合、 HGLOBALを解放、再割り当てするか、または割り当てられたままにします。実際に m_dwDataLengthで使用されるバイト数を示すことを確認します。
CLongBinary を更新できるしくみ
この 3 番目のメソッドを選択すると CLongBinary を更新できるしくみと、次のデータ ソースに長いデータ値を送信する方法の一例として利用方法を理解する必要はありません。
[!メモ]
更新に含める CLongBinary フィールドに対して明示的にフィールドの SetFieldDirty をダイヤルします。これを null 設定を含むフィールドに変更を加えた場合、 SetFieldDirtyをダイヤルします。また FALSEで、 2 番目のパラメーターが SetFieldNullを、ダイヤルし、値を持つとしてフィールドをマークする。
CLongBinary フィールドを更新する場合、データベース クラスは、 ODBC の DATA_AT_EXEC の機能 (SQLSetPos の rgbValue の引数の ODBC のドキュメントを参照してください)。フレームワークが挿入を準備するか、含む HGLOBAL をポイントする代わりに、更新ステートメントとデータは、列の 値 、および SQL_DATA_AT_EXECに設定された長さのインジケーターとして、 CLongBinary の アドレス はに設定されます。更新ステートメントをデータ ソースに送信すると、 SQLExecDirect は SQL_NEED_DATAを返します。これは、その列のパラメーターの値が実際に CLongBinaryのアドレスはいるフレームワークを通知します。フレームワークは、データの実際の時間を返すとドライバーが要求する小さいバッファーとの SQLGetData を一度ダイヤルします。ドライバーがバイナリ ラージ オブジェクト (ブロブ)の実際の時間を返す場合、 MFC はブロブをフェッチために、必要に応じて任意の数の領域を再割り当てします。データ ソースが返す SQL_NO_TOTALのブロブのサイズを決定できないことを示すには、 MFC をより小さなブロックを作成します。既定の初期のサイズは KB で、その後にブロックは double サイズです。; たとえば、 2 番目は、 128K 番目のチュートリアルです 256K などです。初期サイズを構成できます。
バインドする: /SQLGetData の ODBC からデータを直接渡す取得
このメソッドによって完全に長いデータ列によってデータベース クラスと処理を独自にバイパスします。
Sun:
ディスクに、必要に応じてデータをキャッシュすることも、取得するデータの量を動的に決定します。
:短所
フレームワークの 編集 または AddNew サポートを取得し、自分基本機能を実行するコードを記述します (削除 は、列レベルの操作ではないため)、なっています。
この場合、長いデータ列はレコードセットの選択リストにある必要があります、フレームワークによってにバインドすることはできません。これを行うには、 1 とおりの方法は、 SQL ステートメントを GetDefaultSQL して、 lpszSQL の引数として作成し、 RFX_ の関数呼び出しと追加の列をバインドしないように entity_CODECRecordset の 開く(&&O),開く,[開く] の関数に指定することです。ODBC は、非バインド フィールドをバインド フィールドの右に表示されるため、追加する非バインド列または列をことが必要です。選択リストの末尾で。
[!メモ]
長いデータ列がフレームワークによってバインドされていないため、これに対する変更は CRecordset::Update の呼び出しと見なされません。自分で必要な SQL INSERT と UPDATE ステートメントを作成し、送信します。