TN045: 長 Varchar/Varbinary MFC/資料庫支援
注意事項 |
---|
由於它第一次線上文件中包含尚未更新下列技術提示。如此一來,某些程序和主題可能已經過期或不正確。如需最新資訊,建議您先搜尋線上文件索引中有興趣的主題。 |
這個註解告訴您,如何接收及傳送 ODBC SQL_LONGVARCHAR 和 SQL_LONGVARBINARY 的資料型別使用 MFC 資料庫類別。
支援的長 Varchar/Varbinary 概觀
ODBC SQL_LONG_VARCHAR 和 SQL_LONGBINARY (以下統稱 long,其資料行) 的資料型別可以容納大量的資料。 有 3 種方法可以處理這項資料:
Bind it to a CString/CByteArray.
繫結至CLongBinary。
執行不完全將它繫結和接收及傳送長的資料值以手動方式,獨立的資料庫類別。
三種方法各有優點和缺點。
不支援長資料行加入查詢中的參數。 它們都只支援 outputColumns。
繫結至 CString/CByteArray 的長的資料行
優點:
這種方法比較容易了解,而您處理與熟悉的類別。 此架構提供CFormView支援CString與DDX_Text。 您有很大的一般字串或集合的功能與CString和CByteArray類別,以及您可以控制在本機上用於儲存資料值配置的記憶體數量。 此架構會維持在欄位資料的舊複本編輯或AddNew函式呼叫,且架構可以自動偵測您的資料變更。
注意事項 |
---|
因為CString為了使用字元資料,以及CByteArray為處理二進位資料,建議您將字元資料 (SQL_LONGVARCHAR) 到CString,和二進位資料 (SQL_LONGVARBINARY) 到CByteArray。 |
RFX 函式的CString和CByteArray有額外的引數可讓您覆寫的預設大小之配置的記憶體來儲存擷取的資料行的值。 請注意下列函式宣告中的 [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。 幸運的是,您可以明確地增加 nMaxLength 成更大的值,最多 MAXINT。
注意事項 |
---|
NMaxLength 的值來設定本機的緩衝區時,是由 MFC SQLBindColumn 函式。這是針對資料的儲存區域的緩衝區,而且並不會實際影響的 ODBC 驅動程式所傳回的資料量。RFX_Text與RFX_Binary只能幫它建一個呼叫使用 SQLFetch 從後端資料庫擷取資料。每個 ODBC 驅動程式有不同的限制它們可以在使用單一擷取傳回的資料量。這項限制可能得遠小於 nMaxLength,在這種情況的例外狀況的值設定 AFX_SQL_ERROR_DATA_TRUNCATED 就會擲回。在下列情況下,切換為使用RFX_LongBinary而不是RFX_Text或RFX_Binary ,這樣可擷取所有資料。 |
類別精靈將會繫結 SQL_LONGVARCHAR 到CString,(含) SQL_LONGVARBINARY 到CByteArray了。 如果您想要配置超過 255 個位元組您要從其中擷取長資料的資料行,您可以再提供明確的值為 nMaxLength。
當長資料行繫結至CString或CByteArray,更新欄位工作相同當它結合到 SQL_VARCHAR 或 SQL_VARBINARY。 在編輯,離開及更新版本中進行比較時快取的資料值 更新呼叫,是為了偵測變更的資料值,並設定 Dirty 而且適當地 Null 資料行的值。
繫結到 CLongBinary 的長的資料行
如果您很長的資料行可能包含更多 MAXINT 個位元組的資料,您應該考慮擷取成CLongBinary。
優點:
這會擷取整個長資料欄,可用的記憶體。
缺點:
資料會保留在記憶體中。 這種方法也會引致高成本,對於有大量的資料。 您必須呼叫SetFieldDirty的繫結的資料成員,才能確保欄位會包含在更新作業。
如果您擷取到長資料欄CLongBinary,資料庫類別會檢查的總位元組數的 long 資料行,然後再配置HGLOBAL記憶體區段的大小足以容納它的整個資料值。 資料庫類別然後擷取整個資料數值並放入配置HGLOBAL。
如果資料來源無法傳回預期長的資料行的大小,則架構會擲回例外狀況 AFX_SQL_ERROR_SQL_NO_TOTAL。 如果嘗試配置HGLOBAL失敗時,標準的記憶體會擲回例外。
類別精靈將會繫結 SQL_LONGVARCHAR 或 SQL_LONGVARBINARY 到CLongBinary了。 選取 CLongBinary為變數的型別,在 [加入成員變數] 對話方塊。 類別精靈然後將RFX_LongBinary呼叫您DoFieldExchange呼叫,且遞增量為繫結欄位的總數。
若要更新 long,其資料的資料行值,請先確定已配置HGLOBAL夠大,無法保留您的新資料,藉由呼叫 :: GlobalSize 上m_hData成員的CLongBinary。 如果太小,釋放HGLOBAL及配置一個適當的大小。 然後設定m_dwDataLength以反映新的大小。
否則,如果m_dwDataLength大小大於您要取代的資料,您可以釋出,並重新配置HGLOBAL,也可以讓它配置。 請確定表示中實際使用的位元組數目m_dwDataLength。
如何更新 CLongBinary 的運作方式
您不需要了解如何更新CLongBinary有效,但是它可能會很有用,例如如何將長資料值傳送至資料來源,如果您選擇這個第三種方法,如下所述。
注意事項 |
---|
為了讓CLongBinary欄位来包含在更新時,您必須明確地呼叫SetFieldDirty的欄位。如果您作任何修改的欄位,包括將它設定為 Null,您必須呼叫SetFieldDirty。您也必須呼叫SetFieldNull,與第二個參數的 ,則為 FALSE將標示為具有值的欄位。 |
更新時CLongBinary欄位,資料庫類別使用 ODBC 的 DATA_AT_EXEC 機制 (請參閱 ODBC 文件 SQLSetPos的 rgbValue 引數)。 當架構準備 insert 或 update 陳述式,而非指向HGLOBAL其中包含的資料, 位址的CLongBinary已設為 [ 值資料行的相反地,並設為長度指標 SQL_DATA_AT_EXEC。 更新的版本,當 update 陳述式傳送至資料來源, SQLExecDirect 會傳回 SQL_NEED_DATA。 這會改變架構本篇文章中的參數值是實際的地址CLongBinary。 架構呼叫 SQLGetData 一次與小的緩衝區,必須是要傳回資料的實際長度的驅動程式。 如果驅動程式傳回二進位大型物件 (BLOB) 的實際長度,MFC 重新擷取 BLOB 視配置最多的空間。 如果資料來源傳回 SQL_NO_TOTAL,表示它無法判定 BLOB 的大小,MFC 會建立較小的區塊。 預設的初始大小是 64 K 和後續的區塊會放大兩倍。 比方說,第二個 128k,第三個是 256k,以此類推。 初始大小是設定的。
未繫結: 擷取/傳送資料直接從 ODBC 與 SQLGetData
使用這個方法,您完全略過資料庫類別中,並自行處理長資料行。
優點:
您可以快取到磁碟,如有必要,或決定以動態方式多少資料擷取的資料。
缺點:
您沒有做架構的編輯或AddNew支援,而且您必須撰寫您自己,以執行基本功能的程式碼 (刪除運作,因為它不是資料行層級的作業)。
如此一來,很長的資料行必須是資料錄集,與選取清單中,但應該沒有結合到架構。 這是提供您自己的 SQL 陳述式,透過其中一種方式GetDefaultSQL或 lpszSQL 引數至CRecordset的開啟變數,並繫結的 RFX_ 函式呼叫將額外的資料行。 ODBC 需要繫結欄位的右邊顯示未繫結的欄位,因此將您的繫結資料行或資料行加入至選取清單的結尾。
注意事項 |
---|
因為您很長的資料行未繫結架構,它的變更將不無法處理的CRecordset::Update的呼叫。您必須建立並傳送必要的 SQL 插入 和 更新陳述式自行。 |