Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 326
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

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