Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 335
  • Last Modified:

CRowset and MovePrev

What is wrong with this code...


HRESULT hr = m_pSet->MoveLast();
while (hr == S_OK)
{
hr = m_pSet->MovePrev();
}


It is *supposed* to step backwards through the rowset once only, but what I find is that it just keeps going round and round infinitely and never exits the loop?!?

I am completely stumped... what am I missing here? (something obvious no doubt)

I tested the above code by creating a MFC app using the wizard to hook up an OLE DB connection to a Jet database. I am using VS.NET on Windows XP btw.
0
paulburns
Asked:
paulburns
  • 3
  • 2
1 Solution
 
GGRUNDYCommented:
maybe you need

while (hr==S_OK && !m_pSet->IsBOF())
0
 
DanRollinsCommented:
The docs ward agains using CRecordset::MovePrev() without chcking IsBOF().  So the best way to cycle backward would be analogus to
while(!crs.IsEOF() ) { ...crs.MoveNext()... }

while ( !m_pSet->IsBOF() ){
    m_pSet->MovePrev();
}

What I don't understand is why this is not giving you a compiler error:

     hr= m_pSet->MovePrev();

The CRecordset and CDaoRecordset member fns MovePrev() return void, and that attempt to assign the 'return value' of a void fn to your hr variable, is a clear error.  If you are using ADO _Recordsets, there is no MovePrev() fn (only MovePrevious).  

Can you explain?

-- Dan
0
 
paulburnsAuthor Commented:
Maybe I wasn't clear, I am using the OLE DB template classes... CRowset, not CRecordset. According to the docs MovePrev should return DB_S_ENDOFROWSET (i.e. something other than S_OK)  when it gets to the end or beginning of the rowset.


If I try this code to step *forward* through the rowset then it  works....


HRESULT hr = m_pSet->MoveFirst();
while (hr == S_OK)
{
hr = m_pSet->MoveNext();
}


It is only when stepping *backwards* through the rowset that I get the problem described.

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
DanRollinsCommented:
It really helps if you provide a contest.

In the file ATLDBCLI.H, we see that MovePrev is defined as :

HRESULT MovePrev()
{
     return MoveNext(-2, true); // delta, bForward
}

And the relvant part of MoveNext is:

HRESULT MoveNext(LONG lSkip, bool bForward)
      hr = m_spRowset->GetNextRows(NULL, lSkip, (bForward) ? 1 : -1, &ulRowsFetched, &phRow);

which is:
    GetNextRows( 0, -2, 1, &nCnt, &phRow )

So lSkip is -2 and cRows is 1 (requesting forward motion).  

The dox mention that providers implement skipping in various ways.  It seems that the Jet provider is a little wacky or perhaps the template is wrong (why not -1?  why move 'forward by -2 rather than move backward by 1?  

I'd have to guess that it rowset provider moves past the beginning and automatically cycles to the end and so sees no error.

Anyway, I'd try changing your code to this:

//----------------------- I did not test this code.
while (hr == S_OK)
{
     hr = m_pSet->MoveNext( 1, false );
    // or maybe
    // hr = m_pSet->MoveNext( 2, false );
}

That way the low-level GetNextRows() call will pass -1 as the third parameter, which tells the provider to skip backwards.

But the real solution is to check IsBOF() on each loop.

-- Dan
0
 
paulburnsAuthor Commented:
Hi Dan, you aren't Henry's brother by any chance? ;) ...ah poor joke I bet you get that all the time.

Anyway, after some experimenting I found MoveNext(0, false) worked. Now why the hell wasn't MovePrev
implemented this way?!

thanks.
0
 
DanRollinsCommented:
OLE DB is designed to be very general.  I think that the template is implemented that way because some data sources have a lot of trouble moving backwards through a rowset (even though I can't think of why the template's handling would be any safer or more efficient).

-- Dan

BTW, you could have easily solved this yourself by single-stepping through the MovePrev fn; it's only about 10 lines of code.  VC++ debugger is excellent for solving mysteries.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now