FIX: Dynasets w/ CLongBinary Fields Throws Incorrect ExceptionLast reviewed: September 19, 1997Article ID: Q141303 |
The information in this article applies to:
SYMPTOMSAn MFC ODBC application that uses dynaset recordsets with CLongBinary bound fields worked in Visual C++ 2.x, but it throws an exception in Visual C++ 4.0 when the recordset is opened. The CDBException indicates: Data truncated. Additionally, the following trace messages are output (Microsoft Access driver output is shown):
Error in row State:01S01,Native:89,Origin:[Microsoft][ODBC Microsoft Access 7.0 Driver] Data truncated State:01004,Native:2,Origin:[Microsoft][ODBC Microsoft Access 7.0 Driver] Error: field data truncated during Open or Requery. Data truncated.The exception is thrown from CRecordset::InitRecord(). Also, in release builds, the same exception is also thrown by CRecordset::Move().
CAUSEThe exception is thrown incorrectly. The problem is a bug in the MFC code. Both CRecordset::InitRecord() (responsible for initializing the recordset with the first record of the result set) and CRecordset::Move() perform a check following the fetch. If the fetch returns SQL_SUCCESS_WITH_INFO and the subsequent call to SQLError indicates that data was truncated, an exception should only be thrown if snapshots are being used. If the recordset is a dynaset, then data truncation is expected because of the way in which the MFC classes handle binding in dynasets, so it should be ignored. The MFC code performs an incorrect comparison to determine if dynasets are being used resulting in the exact opposite of the desired effect -- exceptions are only thrown if dynasets are being used with CLongBinary fields. The incorrect code is shown below (from CRecordset::InitRecord()):
if (!((m_pDatabase->m_dwUpdateOptions & AFX_SQL_POSITIONEDSQL) && m_bLongBinaryColumns)) { //throw the exception }AFX_SQL_POSITIONEDSQL corresponds to the update option for a snapshot, not a dynaset.
RESOLUTIONUnfortunately, CRecordset::InitRecord() is not a virtual function. Consequently, the two virtual functions that call InitRecord() must be overridden to allow a corrected version of InitRecord() to be called. Note that after you apply the following workaround, the trace messages will still be output but can be safely ignored. NOTE: To assist you in implementing a workaround for this problem, obtain NOTRUNC.EXE: The following file is available for download from the Microsoft Software Library:
~ Notrunc.exe (size: 27189 bytes)For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q119591 TITLE : How to Obtain Microsoft Support Files from Online ServicesAfter running the Notrunc.exe, you will have a custom component file (Notrunc.ogx), .cpp file, .h file, and a Readme.txt file. You can import the .ogx file into the component gallery, and then reuse it as needed. For more information on importing components, see Importing Components in the Visual C++ User's Guide.
Workaround ExampleIf you downloaded Notrunc.exe, go to step 8. If you want to implement the modifications yourself, proceed with step 1:
STATUSMicrosoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This bug was corrected in Visual C++ 4.1.
|
Additional query words: truncation long binary column
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |