Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need help! I program in C++ with MFC and using the CRecordset class.
My problem is I use the Requery() function about 10 times a second during heavy use. After about a hour of this heavy use, the Requery() function stops working; all of the previous Re-querys that worked, no longer works! After about 15 minutes of this error, my program crashes. Has anybody heard of this problem?
Compiled in winXP (32 bit) and windows7 (64bit) with the same results. This error is found to occur in more than 5 computers with MS Access (2003) or SQL (2005). The only thing common is the MSVS2005
I got a free copy of MSVC2005 from Microsoft for taking one of their online courses many years ago; it is a full featured standard edition of Visual Studio 2005.

Does anybody have any clues?

I have 4 threads accessing one function (the problem function) where it funnels down to a shared resource, the database. I use a semaphore so that the "read only" Requery is used one-at-time. One of the fields is a CLongBinary where it holds one picture info to be displayed on the screen when Re-queryied.

sorry about some of the format below, paste but came out different and hand edit to make it readable; hopefully

Below are some code snippets.
ViewClass.cpp
THE REQUERY:
C++
if(m_pCardSet->IsOpen())
{
    m_pCardSet->m_MyParam           = 1;
    m_pCardSet->m_nParams           = 1;
    m_pCardSet->m_strCardNoParam    = CardNo;
    m_pCardSet->m_strFilter         = "CardNo = ?";
    m_pCardSet->Requery();
    if(m_pCardSet->IsEOF() && m_pCardSet->IsBOF())
    {
        p = CardDBQue.RemoveHead();
        n = InterlockedDecrement(&CardDBCount);
        return(_T("NO ENTRIES IN CARDHOLDER DATABASE"));
    }//ONLY ONE RECORD WILL SHOW, NO DUPLICATES
    if( (int)m_pCardSet->m_Image.m_dwDataLength < 100 )
        HAS_PIX = FALSE;
    else
        HAS_PIX = TRUE;

    if(HAS_PIX == TRUE)
        if(CreateStreamOnHGlobal(NULL, TRUE, &pStream) == S_OK)
        {
            LPVOID buffer = GlobalLock(m_pCardSet->m_Image.m_hData);
            pStream->Write(buffer, (UINT)m_pCardSet->m_Image.m_dwDataLength, ulWritten);
            GlobalUnlock(m_pCardSet->m_Image.m_hData);
        }

..... etc.


THE m_pCardSet CLASS: (Standard setup)
C++
class CCardHolderSet : public CRecordset
{
public:
	CCardHolderSet(CDatabase* pDatabase = NULL);
	DECLARE_DYNAMIC(CCardHolderSet)
	CDBpwd		m_dbParam;

	CStringA	m_CardNo;	//Card number 10 digits
	BOOL		m_AntiPass;	//is APB ACTIVE?
	CStringA	m_FirstName;	//CardHolder name (first)
	CStringA	m_LastName;	//CardHolder last name
	CStringA	m_TransCode;	//not sure
	CLongBinary	m_Image;	//picture of cardholder
	CStringA	m_ImageName;	//picture name
	BOOL		m_Voided;	//voided cards
	CStringA	m_SecLevel;		
	CStringA	m_strCardNoParam;
	int		m_MyParam;	//varable to decide which params to use
	////////// PARAMS BELOW,NOT FIELDS //////////////
// Overrides
	// Wizard generated virtual function overrides
	public:
	virtual CString GetDefaultConnect();	// Default connection string
	
	virtual CString GetDefaultSQL(); 	// default SQL for Recordset
	virtual void DoFieldExchange(CFieldExchange* pFX);	// RFX support
// Implementation
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
};


IMPLEMENTAION OF THE CLASS ABOVE:
C++
CCardHolderSet::CCardHolderSet(CDatabase* pdb)
	: CRecordset(pdb)
{
	m_CardNo		= _T("");
	m_AntiPass		= 0;
	m_LastName		= _T("");
	m_FirstName		= _T("");
	m_TransCode		= _T("");
	m_ImageName		= _T("");
	m_Image.m_hData	= 0;
	m_Voided		= FALSE;
	m_SecLevel		= _T("");
	m_nFields		= 9;
	m_nDefaultType          = ConnectType;
	m_strCardNoParam        = _T("");
	
	m_MyParam			= 0;
	m_nParams			= 0;
}
CString CCardHolderSet::GetDefaultConnect()
{
	CString Dsn;
	Dsn.Format("%s%s%s", m_dbParam.DbString,m_dbParam.DbParamStr, m_dbParam.DbLogonStr);
	return(Dsn);
}

CString CCardHolderSet::GetDefaultSQL()
{	
	if(CONNECT_SQL_DB == TRUE)
		return _T("[dbo].[CardHolder]");
	else	
		return _T("[CardHolder]");
}

void CCardHolderSet::DoFieldExchange(CFieldExchange* pFX)
{
	pFX->SetFieldType(CFieldExchange::outputColumn);
	RFX_Text(pFX, _T("[CardNo]"),		m_CardNo);
	RFX_Bool(pFX, _T("[AntiPass]"),		m_AntiPass);
	RFX_Text(pFX, _T("[FirstName]"),	m_FirstName);
	RFX_Text(pFX, _T("[LastName]"),		m_LastName);
	RFX_Text(pFX, _T("[TransCode]"),	m_TransCode);
	RFX_Text(pFX, _T("[ImageName]"),	m_ImageName);//m_PixName);
	RFX_LongBinary(pFX, _T("[Image]"),	m_Image);
	RFX_Bool(pFX, _T("[Voided]"),		m_Voided);
	RFX_Text(pFX, _T("[SecLevel]"),		m_SecLevel, 63999);
	switch(m_MyParam)
	{
		case 1:	
			pFX->SetFieldType(CFieldExchange::param);
			RFX_Text(pFX, "CardNo", m_strCardNoParam);
			break;
		default:
			break;
	}
}


Craig C.
Posted
Updated 4-Nov-16 23:10pm
v2
Comments
Richard MacCutchan 30-Sep-13 12:32pm    
Nothing in the above gives any clue as to what is happening, but it may be a timing issues somewhere. My only comment is that the statement
if(m_pCardSet->IsEOF() && m_pCardSet->IsBOF())
looks wrong, I don't think that both of those conditions can be true at the same time; you probably meant to use the || operator.
Mehdi Gholam 30-Sep-13 13:16pm    
OP :

Hi and thanks for the reply,
I use the EOF && BOF most of the time because it will be true only if there no results; empty sets. If you requery on a non-existant value, you will find it works and only as "&&" and not " ||"
Sorry about the code but this function is the only one that does the requery. The other code(s) is massive, about 100,000 lines just for this project. Using 4 serial ports, 13 threads, 22 tables in either database, 8 stored procedures, 20 class's.
Timing, one at a time but continuous under heavy traffic. This is a security program for card keys/elevators/alarms etc. I would really like to finish this project because its giving me grey hair!

Hi and thanks for the reply,
I use the EOF && BOF most of the time because it will be true only if there no results; empty sets. If you requery on a non-existant value, you will find it works and only as "&&" and not " ||"
Sorry about the code but this function is the only one that does the requery. The other code(s) is massive, about 100,000 lines just for this project. Using 4 serial ports, 13 threads, 22 tables in either database, 8 stored procedures, 20 class's.
Timing, one at a time but continuous under heavy traffic. This is a security program for card keys/elevators/alarms etc. I would really like to finish this project because its giving me grey hair!
 
Share this answer
 
Comments
Richard MacCutchan 30-Sep-13 13:22pm    
Please don't post replies as Solutions. Use the appropriate Reply button.
Richard MacCutchan 30-Sep-13 13:26pm    
However, given your other comments I don't think it would be possible to guess what is happening in such a large project.
Slugging the RecordSet using Requery() will not work. I originally wanted it to have a live update on the program all the time. The workaround is making a dynamically allocated struct holding all the fields of the database and all the rows in memory. Added another table which is TRUE/FALSE if any of the fields were updated by a remote user, this would change to TRUE and then the whole struct would be re-loaded in real-time without disturbing the running program. Its faster than Requery() (ing) the database every 10 msec and memory isn't an issue nowadays.
Requery() is not built to be over-used, it will fail. By that, I mean over-used by requesting it every 10-50 msec for 24 hours a day...YOY then, your HD fails
 
Share this answer
 
Comments
Richard MacCutchan 5-Nov-16 6:26am    
This question is more than 3 years old.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900