15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


RFX_Date & ODBC/Access Problem

Tom P. Bigelow -- iecorp@concentric.net
Thursday, November 14, 1996

Environment: VC++ 4.2b, NT 4.0



Hello,



I am having a problem with an ODBC app that I inherited. We are using
Access as the database. I am getting an exception when adding a record
to an EMPTY database. This DOES NOT happen when the database has at
least one record. The member is a CTime variable as I am storing a date
with RFX_Date.


The error message is typical:
>"Unhandled exception in Ewnt.exe(MFC42D.DLL): 0x00000005: Access Violation."

The debugger stops here (Line: 265 File: C:\MSDEV\mfc\include\AFX.INL):

>_AFX_INLINE int CTime::GetYear() const
>	{ return (GetLocalTm(NULL)->tm_year) + 1900; }

At the exception, here is the "this" pointer:
>+	this	0x0089bc5c {time=-842150451}

OK, the "this" pointer looks unitialized or bogus, but it was fine until
it got to this code:

(Line: 1517 Function: RFX_Date File: C:\MSDEV\mfc\src\DBRFX.CPP)
>
>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_pvFieldProxy[nField-1];
>
>pts->year = (SWORD)value.GetYear();    <== This is where the exception happens
>	

Here is some sample code that starts it all:



>rsFile->AddNew();

>rsFile->m_OrderID = 100;

>rsFile->m_PlotFile = "TEST";

>rsFile->m_Entered = CTime::GetCurrentTime(); <== Member that has failure
>  .

> (more member variable updates)

>  .

>rsFile->Update();

>rsFile->Requery();


The member and the "DoFieldExchange" for the member that fails:

>CTime m_Entered;

>RFX_Date(pFX, _T("[Entered]"), m_Entered);

Sorry this is so long.
Can anyone help me figure out why this is failing? Any suggestions? At
this point I will try anything. I am unable to find



Thanks,

Tom Bigelow

C4 Imaging Systems



Dan Kirby -- dkirby@accessone.com
Friday, November 15, 1996

[Mini-digest: 3 responses]

Hi,
See article Q155721 in the Microsoft Developer Knowledgebase.  You need t=
o
initial the CTime object in the constructor for your recordset class.  Th=
e
wizards fail to do this and this is a bug.  Earlier versions of the MFC
Database classes didn't require that you initialize the CTime object but
4.2 does.

--dan


----------
> From: Tom P. Bigelow 
> To: mfc-l@netcom.com
> Subject: RFX_Date & ODBC/Access Problem
> Date: Thursday, November 14, 1996 12:30 PM
>=20
> Environment: VC++ 4.2b, NT 4.0
>=20
>=20
>=20
> Hello,
>=20
>=20
>=20
> I am having a problem with an ODBC app that I inherited. We are using
> Access as the database. I am getting an exception when adding a record
> to an EMPTY database. This DOES NOT happen when the database has at
> least one record. The member is a CTime variable as I am storing a date
> with RFX_Date.
>=20
>=20
> The error message is typical:
> >"Unhandled exception in Ewnt.exe(MFC42D.DLL): 0x00000005: Access
Violation."
>=20
> The debugger stops here (Line: 265 File: C:\MSDEV\mfc\include\AFX.INL):
>=20
> >_AFX_INLINE int CTime::GetYear() const
> >	{ return (GetLocalTm(NULL)->tm_year) + 1900; }
>=20
> At the exception, here is the "this" pointer:
> >+	this	0x0089bc5c {time=3D-842150451}
>=20
> OK, the "this" pointer looks unitialized or bogus, but it was fine unti=
l
> it got to this code:
>=20
> (Line: 1517 Function: RFX_Date File: C:\MSDEV\mfc\src\DBRFX.CPP)
> >
> >AfxCopyValueByRef(pInfo->m_pvDataCache, &value,
> >     plLength, pInfo->m_nDataType);
> >
> >// Restore proxy for correct WHERE CURRENT OF operations
> >TIMESTAMP_STRUCT* pts =3D
> >     (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
> >
> >pts->year =3D (SWORD)value.GetYear();    <=3D=3D This is where the exc=
eption
happens
> >=09
>=20
> Here is some sample code that starts it all:
>=20
>=20
>=20
> >rsFile->AddNew();
>=20
> >rsFile->m_OrderID =3D 100;
>=20
> >rsFile->m_PlotFile =3D "TEST";
>=20
> >rsFile->m_Entered =3D CTime::GetCurrentTime(); <=3D=3D Member that has=
 failure
> >  .
>=20
> > (more member variable updates)
>=20
> >  .
>=20
> >rsFile->Update();
>=20
> >rsFile->Requery();
>=20
>=20
> The member and the "DoFieldExchange" for the member that fails:
>=20
> >CTime m_Entered;
>=20
> >RFX_Date(pFX, _T("[Entered]"), m_Entered);
>=20
> Sorry this is so long.
> Can anyone help me figure out why this is failing? Any suggestions? At
> this point I will try anything. I am unable to find
>=20
>=20
>=20
> Thanks,
>=20
> Tom Bigelow
>=20
> C4 Imaging Systems
-----From: "Luke Stephens" 

I have this same exact problem and haven't been able to solve it.  I thin=
k
this is a bug in MFC.

In my case, the problem doesn't happen every time.=20

Luke Stephens
luker@tfs.net

-----From: Dong Chen 


        Solution: If you initialize your CTime member variable (m_Entered=
),
such as put the following line in your recordset constructor: m_Entered =3D
CTime::GetCurrentTime(), then you are safe.=20
        Reason: see below.

        But also: If you build your application to the release version, t=
his
problem will be gone.
        Reason: don't know. (so I won't do this)
        There must be something worked differently in the MFC CRecordSet
code, debug version. If you check your table after the crash, you will fi=
nd
out that the record is actually inserted in your table as you desired. Th=
e
access violation happened in the Update() call after the insertion proces=
s.=20

         As I understood, when you use AddNew() to add a new record, the =
RFX
first buffers the current record. At this point, the RFX is called for th=
e
first time. If you don't have your CTime member initialized, it will
probably grab some garbage as you've seen in your "this" pointer. After t=
he
Update() call, it first inserts the record and then trys to restore the
buffered record. Here it calls the CTime member function GetYear(),
GetMonth() etc.  In the case of empty table, there is nothing to buffer s=
o
we all think that the code should be smart enough to bypass the restoring
process. But it didn't. So these member function calls will all fail. If
there is already at least one record in the table, remember when the
recordset=92s Open() is called, the RFX automatically moves to the first
record so there is no problem.

--
Dong
d_chen@ix.netcom.com





| Вернуться в корень Архива |