FIX: CRecordset "String Cannot Be Converted to Number" Error (197448)
The information in this article applies to:
- Microsoft Visual C++, 32-bit Enterprise Edition 5.0
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Open Database Connectivity 3.0
- Microsoft Open Database Connectivity 3.5
- Microsoft Open Database Connectivity 3.51
- Microsoft Open Database Connectivity 3.6
This article was previously published under Q197448 SYMPTOMS
This article explains the consequences of altering the address assigned to
a CRecordset member variable. This problem can occur when the CRecordset
class uses numeric or decimal fields. If the internal buffer changes, the
following error message can occur during a call to CRecordset::Update():
String cannot be converted to number
CAUSE
Each field in a database that is bound to a CRecordset member variable has
a corresponding binding address stored in CRecordset::m_pvBindAddress. This
binding address is the location in memory where data for each field is
placed when ODBC retrieves a record. Once bound, the address of this column
must remain valid as long as the ODBC binding remains in effect. If this
address changes, the CRecordset class can display the following debug TRACE
message when retrieving a record:
Error: field address (column x) has changed
If the field in question is a high precision numeric or decimal field, the
following error may occur while performing a CRecordset::Update():
String cannot be converted to number
RESOLUTION
The MFC CRecordset Class Wizard binds high precision numeric and decimal
fields to CString member variables. The MFC CRecordset class keeps a
pointer to the CString internal buffer in CRecordset::m_pvBindAddress. If
you modify a CString member variable, the CString class may re-allocate
it's string buffer (for example, if you increase the size of the CString).
If this change occurs, the address stored in CRecordset::m_pvBindAddress
becomes invalid.
For example, the CString class can reallocate its internal memory if you
make the following call to CString::Format(...):
CString strNumber;
strNumber.Format( "%6.3f", 123456.123 );
To ensure your CString buffer is large enough, pass a larger value than the
default of 255 to the fourth parameter of RFX_Text (nMaxLength). For
example, the following code demonstrates the before and after of an
RFX_Text call:
// BEFORE
void CMyRecordsSet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CTestRecords)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[UNITS]"), m_UNITS);
//}}AFX_FIELD_MAP
}
// AFTER
void CMyRecordsSet::DoFieldExchange(CFieldExchange* pFX)
{
//{{AFX_FIELD_MAP(CTestRecords)
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[UNITS]"), m_UNITS, 1024);
//}}AFX_FIELD_MAP
}
Modification Type: | Major | Last Reviewed: | 12/11/2003 |
---|
Keywords: | kbbug kbcode kbDatabase kbDriver kberrmsg kbfix kbVS600sp3fix KB197448 |
---|
|