ODBC access violation...
David Little -- dlittle@equinoxcorp.com
Thursday, February 13, 1997
Environment: Win95, VC++ 4.1, PS4.0
I am having a problem with an Access/95 table and ODBC. It seems if I =
delete all the rows in the table, then try to add a new record, I get an =
access violation in this code from dbrfx.cpp, line 1534:
case CFieldExchange::LoadField:
{
// Get the field data
CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
// Restore the status
pFX->m_prs->SetFieldStatus(nField - 1, pInfo->m_bStatus);
// If not NULL, restore the value, length and proxy
if (!pFX->m_prs->IsFieldStatusNull(nField - 1))
{
AfxCopyValueByRef(pInfo->m_pvDataCache, &value,
plLength, pInfo->m_nDataType);
// Restore proxy for correct WHERE CURRENT OF operations
TIMESTAMP_STRUCT* pts (TIMESTAMP_STRUCT*)pFX->m_prs-m_vFieldProxy[nField-];
>> dies here ------ pts->year =3D (SWORD)value.GetYear();
pts->month =3D (UWORD)value.GetMonth();
pts->day =3D (UWORD)value.GetDay();
pts->hour =3D (UWORD)value.GetHour();
pts->minute =3D (UWORD)value.GetMinute();
pts->second =3D (UWORD)value.GetSecond();
pts->fraction =3D 0;
}
else
*plLength =3D SQL_NULL_DATA;
It seems that the value contains a -842150451. This is my code... They =
error occurs when I try to call Update():
void CStartOfDay::ClearRemitHeader()
{
CTerminal* termTable;
CDatabase* m_DB =3D ((CCashWareApp*)AfxGetApp())->GetAppDB();
termTable =3D new CTerminal(m_DB);
CString s;
s.Format("DELETE DISTINCTROW [Remittance Header]"
"FROM [Remittance Header] "
"WHERE (([Remittance Header].Terminal_Number=3D'%s'))",
termTable->GetCurrentTerminalID());
delete termTable;
TRY
{
m_DB->ExecuteSQL(s);
}
CATCH_ALL(e)
{
CString es;
LPTSTR pe =3D es.GetBuffer(255);
e->GetErrorMessage(pe, 255, NULL);
es.ReleaseBuffer();
AfxMessageBox(es);
}
END_CATCH_ALL;
CRemitMaster* rm =3D new CRemitMaster(m_DB);
TRY
{
rm->Open(CRecordset::dynaset);
if(rm->IsEOF() && rm->IsBOF())
{
rm->AddNew();
rm->m_Terminal_Number =3D "99";
rm->m_Receipt_Number =3D "1000";
rm->m_Transaction_Number =3D "1000";
rm->m_Amount =3D "0";
rm->Update();
rm->Close();
}
}
CATCH_ALL(e)
{
CString es;
LPTSTR pe =3D es.GetBuffer(255);
e->GetErrorMessage(pe, 255, NULL);
es.ReleaseBuffer();
AfxMessageBox(es);
}
END_CATCH_ALL;
delete rm;
}
If the delete happens to leave a record in the table, everything works
fine...
Please Help!
Thanks!
Dan Frankowski -- dsfrankowski@mmm.com
Monday, February 17, 1997
Environment: NT 3.51, VC++ 4.2-flat
I'm having the same problem: when I try to AddNew() a CRecordSet with
a CTime in it to an empty table using ODBC, it crashes on the Update()
in CTime::GetYear() because the code in RFX_Date() tries to GetYear()
from an invalid CTime in the same code referenced in the previous
email. If the table is not empty, it's fine. This crash does not
show up in a table with only a single CTime in it, so it's not trivial
to reproduce.
I've seen this crash using Microsoft SQL Server 6.5 or Sybase 10.
If anyone finds out what's going on, I'd appreciate a pointer.
Also, I ran with purify, and CRecordSet::GetRowStatus [afxdb.inl:71 in
VC++ 4.2] shows an uninitialized memory read for the Microsoft
m_rgRowStatus[wRow-1] variable. I don't know if that's related. This
might be a bug.
I have not yet tried 4.2b. I know I should, but there are only so
many hours in the day. If it's a bug, maybe Microsoft fixed it in 4.2b.
Dan Frankowski
--
3M Corporate Research Lab - Sage Group dsfrankowski@mmm.com
3M Center Bldg. 260-6A08 ph. 612-737-8813
Maplewood, MN 55144 fax 612-733-2165
David Little -- dlittle@equinoxcorp.com
Monday, February 17, 1997
[Mini-digest: 2 responses]
I figured out the answer, so anyone with this problem can repeat it:
MFC never initializes CTime variables, so you must do it manually. See =
the CRecordset constructor that MFC builds. All you have to do is add a =
m_CtimeVariable =3D CTime(NULL) ; for each CTime field. I finally =
noticed that the value that was causing the access violation was the =
same value as if I had created a CTime variable with no parameters, id: =
CTime t;...
If anybody knows the reason, I would like to know...
Thanks!
David
----------
From: Dan Frankowski[SMTP:dsfrankowski@mmm.com]
Sent: Monday, February 17, 1997 2:25 PM
To: mfc-l@netcom.com
Cc: dlittle@equinoxcorp.com
Subject: Re: ODBC access violation...
Environment: NT 3.51, VC++ 4.2-flat
I'm having the same problem: when I try to AddNew() a CRecordSet with
a CTime in it to an empty table using ODBC, it crashes on the Update()
in CTime::GetYear() because the code in RFX_Date() tries to GetYear()
from an invalid CTime in the same code referenced in the previous
email. If the table is not empty, it's fine. This crash does not
show up in a table with only a single CTime in it, so it's not trivial
to reproduce.
I've seen this crash using Microsoft SQL Server 6.5 or Sybase 10.
If anyone finds out what's going on, I'd appreciate a pointer.
Also, I ran with purify, and CRecordSet::GetRowStatus [afxdb.inl:71 in
VC++ 4.2] shows an uninitialized memory read for the Microsoft
m_rgRowStatus[wRow-1] variable. I don't know if that's related. This
might be a bug.
I have not yet tried 4.2b. I know I should, but there are only so
many hours in the day. If it's a bug, maybe Microsoft fixed it in 4.2b.
Dan Frankowski
--=20
3M Corporate Research Lab - Sage Group dsfrankowski@mmm.com =20
3M Center Bldg. 260-6A08 ph. 612-737-8813
Maplewood, MN 55144 fax 612-733-2165
-----From: David Little
Since posting this problem, I have found the solution. It seems that =
MFC/ClassWizard doesn't initialize a CTime field in the =
CRecordset-derived constructor. The solution is to add an initializer =
for each CTime field and everything will be fine. It isn't necessary to =
change anything else. I did it like this:
m_SomeCTimeDatabaseField =3D CTime(NULL);
Be sure and add it outside of the ClassWizard comments, or it will =
disappear the next time you run CW....
David
----------
From: Dan Frankowski[SMTP:dsfrankowski@mmm.com]
Sent: Monday, February 17, 1997 2:25 PM
To: mfc-l@netcom.com
Cc: dlittle@equinoxcorp.com
Subject: Re: ODBC access violation...
Environment: NT 3.51, VC++ 4.2-flat
I'm having the same problem: when I try to AddNew() a CRecordSet with
a CTime in it to an empty table using ODBC, it crashes on the Update()
in CTime::GetYear() because the code in RFX_Date() tries to GetYear()
from an invalid CTime in the same code referenced in the previous
email. If the table is not empty, it's fine. This crash does not
show up in a table with only a single CTime in it, so it's not trivial
to reproduce.
I've seen this crash using Microsoft SQL Server 6.5 or Sybase 10.
If anyone finds out what's going on, I'd appreciate a pointer.
Also, I ran with purify, and CRecordSet::GetRowStatus [afxdb.inl:71 in
VC++ 4.2] shows an uninitialized memory read for the Microsoft
m_rgRowStatus[wRow-1] variable. I don't know if that's related. This
might be a bug.
I have not yet tried 4.2b. I know I should, but there are only so
many hours in the day. If it's a bug, maybe Microsoft fixed it in 4.2b.
Dan Frankowski
--=20
3M Corporate Research Lab - Sage Group dsfrankowski@mmm.com =20
3M Center Bldg. 260-6A08 ph. 612-737-8813
Maplewood, MN 55144 fax 612-733-2165
Mike Blaszczak -- mikeblas@nwlink.com
Thursday, February 20, 1997
At 17:27 2/17/97 -0600, dlittle@equinoxcorp.com wrote:
>If anybody knows the reason, I would like to know...
Performance. We wanted to avoid initializing something that's usually
assigned to something else, anyway. This is particularly important when
you're dealing with arrays of CTime objects.
You'll find that _no_ MFC simple data types are initialized,
including CRect and CTime and CPoint. The documentation even syays so:
CTime( );=A0=A0=A0Constructs an unitialized CTime object.=20
.B ekiM
http://www.nwlink.com/~mikeblas/
These words are my own. I do not speak on behalf of Microsoft.
This performance was not lip-synched.
Become an MFC-L member
| Вернуться в корень Архива
|