FIX: Dynasets w/ CLongBinary Fields Throws Incorrect ExceptionID: Q141303
|
An 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]
The exception is thrown from CRecordset::InitRecord(). Also, in release builds, the same exception is also thrown by CRecordset::Move().Error: field data truncated during Open or Requery. Data truncated.
The 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.
Unfortunately, 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.exeFor more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
Q119591 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.
class CNewDatabase : public CDatabase
{
friend class CNewRecordset;
};
m_pDatabase->m_dwUpdateOptions
With:
((CNewDatabase *)m_pDatabase)->m_dwUpdateOptions
Replace 2 occurrences of:
AFX_SQL_POSITIONEDSQL
With:
AFX_SQL_SETPOSUPDATES
Replace 2 occurrences of:
InitRecord
With:
NewInitRecord
class CMySet : public CNewRecordset
CMySet::CMySet(CDatabase* pdb) : CNewRecordset(pdb)
Microsoft 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: kbVC400bug truncation long binary column
Keywords : kbcode kbDatabase kbMFC kbODBC kbVC kbVC410fix
Version : 4.0
Platform : NT WINDOWS
Issue type :
Last Reviewed: August 2, 1999